Move some queries from Display.php to thier own functions Not replacing everything, just trying out if this is useful at all. See merge request !2
2374 lines
95 KiB
PHP
2374 lines
95 KiB
PHP
<?php
|
|
/******************************************************************************
|
|
* Subs.php *
|
|
*******************************************************************************
|
|
* SMF: Simple Machines Forum *
|
|
* Open-Source Project Inspired by Zef Hemel (zef@zefhemel.com) *
|
|
* =========================================================================== *
|
|
* Software Version: SMF 1.0.6 *
|
|
* Software by: Simple Machines (http://www.simplemachines.org) *
|
|
* Copyright 2001-2005 by: Lewis Media (http://www.lewismedia.com) *
|
|
* Support, News, Updates at: http://www.simplemachines.org *
|
|
*******************************************************************************
|
|
* This program is free software; you may redistribute it and/or modify it *
|
|
* under the terms of the provided license as published by Lewis Media. *
|
|
* *
|
|
* This program is distributed in the hope that it is and will be useful, *
|
|
* but WITHOUT ANY WARRANTIES; without even any implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
* See the "license.txt" file for details of the Simple Machines license. *
|
|
* The latest version can always be found at http://www.simplemachines.org. *
|
|
******************************************************************************/
|
|
if (!defined('SMF'))
|
|
die('Hacking attempt...');
|
|
|
|
/* This file has all the main functions in it that relate to, well,
|
|
everything. It provides all of the following functions:
|
|
|
|
resource db_query(string database_query, string __FILE__, int __LINE__)
|
|
- should always be used in place of mysql_query.
|
|
- executes a query string, and implements needed error checking.
|
|
- always use the magic constants __FILE__ and __LINE__.
|
|
- returns a MySQL result resource, to be freed with mysql_free_result.
|
|
|
|
int db_affected_rows()
|
|
- should always be used in place of db_insert_id.
|
|
- returns the number of affected rows by the most recently executed
|
|
query.
|
|
- handles the current connection so the forum with other connections
|
|
active at the same time.
|
|
|
|
int db_insert_id()
|
|
- should always be used in place of mysql_insert_id.
|
|
- returns the most recently generated auto_increment column.
|
|
- handles the current connection so the forum with other connections
|
|
active at the same time.
|
|
|
|
void updateLastMessages(array ID_BOARDs)
|
|
- takes an array of board IDs and updates their last messages.
|
|
- if the board has a parent, that parent board is also automatically
|
|
updated.
|
|
- columns updated are ID_LAST_MSG and lastUpdated.
|
|
- note that ID_LAST_MSG should always be updated using this function,
|
|
and is not automatically updated upon other changes.
|
|
|
|
void updateStats(string statistic, string condition = '1')
|
|
- statistic can be 'member', 'message', 'topic', 'calendar', or
|
|
'postgroups'.
|
|
- the condition is optional, and is only used to update post groups.
|
|
- the 'member' statistic updates the latest member, the total member
|
|
count, and the number of unapproved members.
|
|
- updating 'message' changes the total number of messages, and the
|
|
highest message id by ID_MSG.
|
|
- 'topic' updates the total number of topics.
|
|
- the 'calendar' statistic updates the cache of the calendar
|
|
information for a day before and after today.
|
|
- the 'postgroups' case updates those members who match condition's
|
|
post-based membergroups in the database.
|
|
|
|
void updateMemberData(int ID_MEMBER, array data)
|
|
- updates the columns in the members table.
|
|
- ID_MEMBER is either an int or an array of ints to be updated.
|
|
- data is an associative array of the columns to be updated and their
|
|
respective values.
|
|
- any string values updated should be quoted and slashed.
|
|
- the value of any column can be '+' or '-', which mean 'increment'
|
|
and decrement, respectively.
|
|
- if the member's post number is updated, updates their post groups.
|
|
- this function should be used whenever member data needs to be
|
|
updated in place of an UPDATE query.
|
|
|
|
void updateSettings(array changeArray)
|
|
- updates both the settings table and $modSettings array.
|
|
- all of changeArray's indexes and values are assumed to have escaped
|
|
apostrophes (')!
|
|
- if a variable is already set to what you want to change it to, that
|
|
variable will be skipped over; it would be unnecessary to reset.
|
|
|
|
string constructPageIndex(string base_url, int &start, int max_value,
|
|
int num_per_page, bool compact_start = false)
|
|
- builds the page list, e.g. 1 ... 6 7 [8] 9 10 ... 15.
|
|
- compact_start caused it to use "url.page" instead of
|
|
"url;start=page".
|
|
- handles any wireless settings (adding special things to URLs.)
|
|
- very importantly, cleans up the start value passed, and forces it to
|
|
be a multiple of num_per_page.
|
|
- also checks that start is not more than max_value.
|
|
- base_url should be the URL without any start parameter on it.
|
|
- uses the compactTopicPagesEnable and compactTopicPagesContiguous
|
|
settings to decide how to display the menu.
|
|
- an example is available near the function definition.
|
|
|
|
string comma_format(float number)
|
|
- formats a number to display in the style of the admins' choosing.
|
|
- uses the format of number_format to decide how to format the number.
|
|
- for example, it might display "1 234,50".
|
|
- caches the formatting data from the setting for optimization.
|
|
|
|
string timeformat(int time, bool show_today = true)
|
|
- returns a pretty formated version of time based on the user's format
|
|
in $user_info['time_format'].
|
|
- applies any necessary time offsets to the timestamp.
|
|
- if todayMod is set and show_today was not not specified or true, an
|
|
alternate format string is used to show the date with something to
|
|
show it is "today" or "yesterday".
|
|
- performs localization (more than just strftime would do alone.)
|
|
|
|
string un_htmlspecialchars(string text)
|
|
- removes the base entities (<, ", etc.) from text.
|
|
- should be used instead of html_entity_decode for PHP version
|
|
compatibility reasons.
|
|
- additionally converts and '.
|
|
|
|
int forum_time(bool use_user_offset = true)
|
|
- returns the current time with offsets.
|
|
- always applies the offset in the time_offset setting.
|
|
- if use_user_offset is true, applies the user's offset as well.
|
|
- returns seconds since the unix epoch.
|
|
|
|
string doUBBC(string message, bool enableSmileys = true)
|
|
- parses bbc tags in message.
|
|
- only parses smileys if enableSmileys is true.
|
|
- does nothing if the enableBBC setting is off.
|
|
- applies the fixLongWords magic if the setting is set to on.
|
|
- returns the modified message.
|
|
|
|
void parsecode(string &message)
|
|
- this very hefty function does the bulk of message parsing.
|
|
- only parses BBC tags which are not disabled in disabledBBC.
|
|
- also handles basic HTML, if enablePostHTML is on.
|
|
- caches the from/to replace regular expressions so as not to reload
|
|
them every time a string is parsed.
|
|
- returns nothing, but instead modifies message directly.
|
|
|
|
void parsesmileys(string &message)
|
|
- the smiley parsing function which makes pretty faces appear :).
|
|
- if custom smiley sets are turned off by smiley_enable, the default
|
|
set of smileys will be used.
|
|
- these are specifically not parsed in code tags [url=mailto:Dad@blah.com]
|
|
- caches the smileys from the database or array in memory.
|
|
- doesn't return anything, but rather modifies message directly.
|
|
|
|
string highlight_php_code(string code)
|
|
- Uses PHP's highlight_code() to highlight PHP syntax
|
|
- does special handling to keep the tabs in the code available.
|
|
- used to parse PHP code from inside [code] and [php] tags.
|
|
- returns the code with highlighted HTML.
|
|
|
|
void writeLog(bool force = false)
|
|
// !!!
|
|
|
|
void redirectexit(string setLocation = '', bool add = true, bool refresh = false)
|
|
// !!!
|
|
|
|
void obExit(bool do_header = true, bool do_footer = do_header)
|
|
// !!!
|
|
|
|
void adminIndex($area)
|
|
// !!!
|
|
|
|
int logAction($action, $extra = array())
|
|
// !!!
|
|
|
|
void trackStats($stats = array())
|
|
- caches statistics changes, and flushes them if you pass nothing.
|
|
- if '+' is used as a value, it will be incremented.
|
|
- does not actually commit the changes until the end of the page view.
|
|
- depends on the trackStats setting.
|
|
|
|
void spamProtection(string error_type)
|
|
- attempts to protect from spammed messages and the like.
|
|
- takes a $txt index. (not an actual string.)
|
|
- depends on the spamWaitTime setting.
|
|
|
|
array url_image_size(string url)
|
|
- uses getimagesize() to determine the size of a file.
|
|
- attempts to connect to the server first so it won't time out.
|
|
- returns false on failure, otherwise the output of getimagesize().
|
|
|
|
void determineTopicClass(array &topic_context)
|
|
// !!!
|
|
|
|
void setupThemeContext()
|
|
// !!!
|
|
|
|
void template_rawdata()
|
|
// !!!
|
|
|
|
void template_header()
|
|
// !!!
|
|
|
|
void theme_copyright(bool get_it = false)
|
|
// !!!
|
|
|
|
void template_footer()
|
|
// !!!
|
|
|
|
void db_debug_junk()
|
|
// !!!
|
|
|
|
void getAttachmentFilename(string filename, int ID_ATTACH, bool new = true)
|
|
// !!!
|
|
*/
|
|
// Find the earliest unread message in the topic. (the use of topics here is just for both tables.)
|
|
function getFirstUnreadPostTimestamp($topic, $board, $user) {
|
|
$request = db_query("
|
|
SELECT IFNULL(lt.logTime, IFNULL(lmr.logTime, 0)) AS logTime
|
|
FROM {$db_prefix}topics AS t
|
|
LEFT JOIN ${db_prefix}log_topics AS lt ON (lt.ID_TOPIC = '${topic}' AND lt.ID_MEMBER = '${user}')
|
|
LEFT JOIN ${db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = '${board}' AND lmr.ID_MEMBER = '${user}')
|
|
WHERE t.ID_TOPIC = '${topic}'
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
list ($logTime) = mysql_fetch_row($request);
|
|
mysql_free_result($request);
|
|
return $logTime;
|
|
}
|
|
# bump number of topic views, if necessary
|
|
function updateTopicViews($topic) {
|
|
global $db_prefix;
|
|
db_query("
|
|
UPDATE {$db_prefix}topics
|
|
SET numViews = numViews + 1
|
|
WHERE ID_TOPIC = $topic
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
}
|
|
|
|
function getSiblingTopic($topic, $board, $direction) {
|
|
global $db_prefix;
|
|
global $modSettings;
|
|
|
|
// Just prepare some variables that are used in the query.
|
|
$gt_lt = $direction == 'prev' ? '>' : '<';
|
|
$order = $direction == 'prev' ? 'ASC' : 'DESC';
|
|
|
|
$request = db_query("
|
|
SELECT t2.ID_TOPIC
|
|
FROM ${db_prefix}topics AS t, ${db_prefix}topics AS t2, ${db_prefix}messages AS m, ${db_prefix}messages AS m2
|
|
WHERE m.ID_MSG = t.ID_LAST_MSG
|
|
AND t.ID_TOPIC = ${topic}" . (empty($modSettings['enableStickyTopics']) ? "
|
|
AND m2.posterTime ${gt_lt} m.posterTime" : "
|
|
AND ((m2.posterTime ${gt_lt} m.posterTime AND t2.isSticky ${gt_lt}= t.isSticky) OR t2.isSticky ${gt_lt} t.isSticky)") . "
|
|
AND t2.ID_LAST_MSG = m2.ID_MSG
|
|
AND t2.ID_BOARD = ${board}
|
|
ORDER BY" . (empty($modSettings['enableStickyTopics']) ? '' : " t2.isSticky ${order},") . " m2.posterTime ${order}
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
|
|
// No more left.
|
|
if (mysql_num_rows($request) == 0)
|
|
return NULL;
|
|
|
|
// Now you can be sure $topic is the ID_TOPIC to view.
|
|
list ($sibling_topic) = mysql_fetch_row($request);
|
|
mysql_free_result($request);
|
|
return $sibling_topic;
|
|
}
|
|
|
|
function getRelatedTopics($topic) {
|
|
global $db_prefix;
|
|
|
|
$query=db_query("
|
|
SELECT t.ID_TOPIC AS id, msg.subject AS subj
|
|
FROM ${db_prefix}related_topics rt
|
|
INNER JOIN ${db_prefix}topics t ON (t.ID_TOPIC=rt.ID_slave)
|
|
INNER JOIN ${db_prefix}messages msg ON (msg.ID_MSG=t.ID_FIRST_MSG)
|
|
WHERE rt.ID_master=${topic}", __FILE__, __LINE__);
|
|
|
|
// Nothing?
|
|
if(mysql_num_rows($query)==0) return array();
|
|
|
|
// fetch 'em all!
|
|
while ($related_topics[] = mysql_fetch_assoc($query));
|
|
return $related_topics;
|
|
}
|
|
|
|
function getTopicInfo($topic, $user) {
|
|
global $db_prefix;
|
|
|
|
$query = db_query("
|
|
SELECT
|
|
t.numReplies, t.numViews, t.locked, ms.subject, t.isSticky, t.isFirstSticky, t.ID_POLL,
|
|
t.ID_MEMBER_STARTED, IFNULL(lt.logTime, 0) AS logTime, t.ID_FIRST_MSG, t.subtitle AS subtitle
|
|
FROM (${db_prefix}topics AS t, ${db_prefix}messages AS ms)
|
|
LEFT JOIN ${db_prefix}log_topics AS lt ON (lt.ID_TOPIC = ${topic} AND lt.ID_MEMBER = ${user})
|
|
WHERE t.ID_TOPIC = ${topic}
|
|
AND ms.ID_MSG = t.ID_FIRST_MSG
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
|
|
if (mysql_num_rows($query) == 0) return NULL;
|
|
|
|
return mysql_fetch_assoc($query);
|
|
}
|
|
|
|
// Do a query. Takes care of errors too.
|
|
function db_query($db_string, $file, $line)
|
|
{
|
|
global $db_cache, $db_count, $db_connection, $modSettings;
|
|
# $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2);
|
|
#
|
|
# $_file=str_replace('/var/www/rock/forum/','',$file);
|
|
# $timer = pinba_timer_start(array("component" => 'db_query', 'function' => (isset ($trace[1]) ? $trace[1]['function'] : ''), 'location' => "{$_file}:{$line}"));
|
|
|
|
// One more query....
|
|
$db_count = !isset($db_count) ? 1 : $db_count + 1;
|
|
|
|
// Debugging.
|
|
if (isset($GLOBALS['db_show_debug']) && $GLOBALS['db_show_debug'] === true)
|
|
{
|
|
$db_cache[$db_count]['q'] = $db_string;
|
|
$db_cache[$db_count]['f'] = $file;
|
|
$db_cache[$db_count]['l'] = $line;
|
|
$st = explode(' ', microtime());
|
|
}
|
|
|
|
// First, we clean strings out of the query, reduce whitespace, lowercase, and trim - so we can check it over.
|
|
if (empty($modSettings['disableQueryCheck']))
|
|
{
|
|
$clean = '';
|
|
$old_pos = 0;
|
|
$pos = -1;
|
|
while (true)
|
|
{
|
|
$pos = strpos($db_string, '\'', $pos + 1);
|
|
if ($pos === false)
|
|
break;
|
|
$clean .= substr($db_string, $old_pos, $pos - $old_pos);
|
|
|
|
while (true)
|
|
{
|
|
$pos1 = strpos($db_string, '\'', $pos + 1);
|
|
$pos2 = strpos($db_string, '\\', $pos + 1);
|
|
if ($pos1 === false)
|
|
break;
|
|
elseif ($pos2 == false || $pos2 > $pos1)
|
|
{
|
|
$pos = $pos1;
|
|
break;
|
|
}
|
|
|
|
$pos = $pos2 + 1;
|
|
}
|
|
$clean .= '%s';
|
|
|
|
$old_pos = $pos + 1;
|
|
}
|
|
$clean .= substr($db_string, $old_pos);
|
|
$clean = trim(strtolower(preg_replace(array('~\s+~s', '~/\*!40001 SQL_NO_CACHE \*/~', '~/\*!40000 USE INDEX \([A-Za-z\_]+?\) \*/~'), array(' ', '', ''), $clean)));
|
|
|
|
// We don't use UNION in SMF, at least so far. But it's useful for injections.
|
|
if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)
|
|
$fail = true;
|
|
// Comments? We don't use comments in our queries, we leave 'em outside!
|
|
elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false)
|
|
$fail = true;
|
|
// Trying to change passwords, slow us down, or something?
|
|
elseif (strpos($clean, 'set password') !== false && preg_match('~(^|[^a-z])set password($|[^[a-z])~s', $clean) != 0)
|
|
$fail = true;
|
|
elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)
|
|
$fail = true;
|
|
// Sub selects? We don't use those either.
|
|
elseif (preg_match('~\([^)]*?select~s', $clean) != 0)
|
|
$fail = true;
|
|
|
|
if (!empty($fail))
|
|
{
|
|
log_error('Hacking attempt...' . "\n" . $db_string, $file, $line);
|
|
fatal_error('Hacking attempt...', false);
|
|
}
|
|
}
|
|
|
|
$ret = mysql_query($db_string, $db_connection);
|
|
if ($ret === false)
|
|
$ret = db_error($db_string, $file, $line);
|
|
|
|
// Debugging.
|
|
if (isset($GLOBALS['db_show_debug']) && $GLOBALS['db_show_debug'] === true)
|
|
{
|
|
$end = explode(' ', microtime());
|
|
$db_cache[$db_count]['t'] = $end[0] + $end[1] - $st[0] - $st[1];
|
|
}
|
|
|
|
# pinba_timer_stop($timer);
|
|
return $ret;
|
|
}
|
|
|
|
function db_affected_rows()
|
|
{
|
|
global $db_connection;
|
|
|
|
return mysql_affected_rows($db_connection);
|
|
}
|
|
|
|
function db_insert_id()
|
|
{
|
|
global $db_connection;
|
|
|
|
return mysql_insert_id($db_connection);
|
|
}
|
|
|
|
// Update the last message in a board, and its parents.
|
|
function updateLastMessages($setboards)
|
|
{
|
|
global $db_prefix, $board_info, $board;
|
|
|
|
if (!is_array($setboards))
|
|
$setboards = array($setboards);
|
|
|
|
// Find the latest message on this board. (highest ID_MSG)
|
|
$result = db_query("
|
|
SELECT ID_BOARD, MAX(ID_MSG) AS ID_MSG
|
|
FROM ${db_prefix}messages
|
|
WHERE ID_BOARD" . (count($setboards) == 1 ? " = $setboards[0]" : ' IN (' . implode(', ', $setboards) . ')') . "
|
|
GROUP BY ID_BOARD", __FILE__, __LINE__);
|
|
$setboards = array_flip($setboards);
|
|
while ($row = mysql_fetch_assoc($result))
|
|
{
|
|
// Okay, this board is done ;).
|
|
unset($setboards[$row['ID_BOARD']]);
|
|
$rPosterTime = db_query("SELECT posterTime FROM ${db_prefix}messages WHERE ID_MSG={$row['ID_MSG']}", __FILE__, __LINE__);
|
|
list($posterTime) = mysql_fetch_row($rPosterTime);
|
|
|
|
// Update the board!
|
|
db_query("
|
|
UPDATE ${db_prefix}boards
|
|
SET ID_LAST_MSG = $row[ID_MSG], lastUpdated = $posterTime
|
|
WHERE ID_BOARD = $row[ID_BOARD]
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
|
|
// The loadBoard function hasn't loaded this board yet?
|
|
if (empty($board) || $board != $row['ID_BOARD'])
|
|
$the_parent_boards = getBoardParents($row['ID_BOARD']);
|
|
else
|
|
$the_parent_boards = $board_info['parent_boards'];
|
|
|
|
if (isset($the_parent_boards[$row['ID_BOARD']]))
|
|
unset($the_parent_boards[$row['ID_BOARD']]);
|
|
|
|
$the_parent_boards = array_keys($the_parent_boards);
|
|
|
|
// If the board has parents update them too.
|
|
if (!empty($the_parent_boards))
|
|
{
|
|
db_query("
|
|
UPDATE ${db_prefix}boards
|
|
SET lastUpdated = $posterTime
|
|
WHERE ID_BOARD IN (" . implode(',', $the_parent_boards) . ")
|
|
AND lastUpdated < $posterTime
|
|
AND childLevel != 0
|
|
LIMIT " . count($the_parent_boards), __FILE__, __LINE__);
|
|
|
|
// Don't do them twice.
|
|
foreach ($the_parent_boards as $ID_BOARD)
|
|
if (isset($setboards[$ID_BOARD]))
|
|
unset($setboards[$ID_BOARD]);
|
|
}
|
|
}
|
|
|
|
if (!empty($setboards))
|
|
db_query("
|
|
UPDATE ${db_prefix}boards
|
|
SET ID_LAST_MSG = 0
|
|
WHERE ID_BOARD IN (" . implode(', ', array_keys($setboards)) . ")
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
}
|
|
|
|
// Update some basic statistics...
|
|
function updateStats($type, $condition = '1')
|
|
{
|
|
global $db_prefix, $sourcedir, $modSettings;
|
|
|
|
switch ($type)
|
|
{
|
|
case 'member':
|
|
// Update the latest member (highest ID_MEMBER) and count.
|
|
$result = db_query("
|
|
SELECT COUNT(ID_MEMBER), MAX(ID_MEMBER)
|
|
FROM ${db_prefix}members", __FILE__, __LINE__);
|
|
list ($memberCount, $latestmember) = mysql_fetch_row($result);
|
|
mysql_free_result($result);
|
|
|
|
// Get the latest member's display name.
|
|
$result = db_query("
|
|
SELECT IFNULL(realName, memberName) AS realName
|
|
FROM ${db_prefix}members
|
|
WHERE ID_MEMBER = " . (int) $latestmember . "
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
list ($latestRealName) = mysql_fetch_row($result);
|
|
mysql_free_result($result);
|
|
|
|
// Update the amount of members awaiting approval.
|
|
if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 2)
|
|
{
|
|
$result = db_query("
|
|
SELECT COUNT(ID_MEMBER)
|
|
FROM ${db_prefix}members
|
|
WHERE is_activated = 0
|
|
AND validation_code = ''", __FILE__, __LINE__);
|
|
list ($unapprovedCount) = mysql_fetch_row($result);
|
|
mysql_free_result($result);
|
|
}
|
|
else
|
|
$unapprovedCount = $modSettings['unapprovedMembers'];
|
|
|
|
updateSettings(array(
|
|
'latestMember' => $latestmember,
|
|
'latestRealName' => $latestRealName,
|
|
'memberCount' => $memberCount,
|
|
'unapprovedMembers' => $unapprovedCount
|
|
));
|
|
break;
|
|
case 'message':
|
|
// Get the number of messages...
|
|
$result = db_query("
|
|
SELECT COUNT(ID_MSG) AS totalMessages, MAX(ID_MSG) AS maxMsgID
|
|
FROM ${db_prefix}messages", __FILE__, __LINE__);
|
|
$row = mysql_fetch_assoc($result);
|
|
mysql_free_result($result);
|
|
|
|
updateSettings(array(
|
|
'totalMessages' => $row['totalMessages'],
|
|
'maxMsgID' => $row['maxMsgID']
|
|
));
|
|
break;
|
|
case 'topic':
|
|
// Get the number of topics.
|
|
$result = db_query("
|
|
SELECT COUNT(ID_TOPIC) AS totalTopics
|
|
FROM ${db_prefix}topics", __FILE__, __LINE__);
|
|
$row = mysql_fetch_assoc($result);
|
|
mysql_free_result($result);
|
|
|
|
updateSettings(array('totalTopics' => $row['totalTopics']));
|
|
break;
|
|
case 'calendar':
|
|
require_once($sourcedir . '/Calendar.php');
|
|
|
|
// Calculate the YYYY-MM-DD of the lowest and highest days.
|
|
$low_date = strftime('%Y-%m-%d', forum_time(false) - 24 * 3600);
|
|
$high_date = strftime('%Y-%m-%d', forum_time(false) + $modSettings['cal_days_for_index'] * 24 * 3600);
|
|
|
|
$holidays = calendarHolidayArray($low_date, $high_date);
|
|
$bday = calendarBirthdayArray($low_date, $high_date);
|
|
$events = calendarEventArray($low_date, $high_date, false);
|
|
|
|
// Cache the results in the settings.
|
|
updateSettings(array(
|
|
'cal_today_updated' => strftime('%Y%m%d', forum_time(false)),
|
|
'cal_today_holiday' => addslashes(serialize($holidays)),
|
|
'cal_today_birthday' => addslashes(serialize($bday)),
|
|
'cal_today_event' => addslashes(serialize($events))
|
|
));
|
|
break;
|
|
case 'postgroups':
|
|
// Fetch postgroups.
|
|
$request = db_query("
|
|
SELECT ID_GROUP, minPosts
|
|
FROM ${db_prefix}membergroups
|
|
WHERE minPosts != -1", __FILE__, __LINE__);
|
|
$postgroups = array();
|
|
while ($row = mysql_fetch_assoc($request))
|
|
$postgroups[$row['ID_GROUP']] = $row['minPosts'];
|
|
mysql_free_result($request);
|
|
|
|
// Oh great, they've screwed their post groups.
|
|
if (empty($postgroups))
|
|
return;
|
|
|
|
// Sort them this way because if it's done with MySQL it causes a filesort :(.
|
|
arsort($postgroups);
|
|
|
|
// Set all membergroups from most posts to least posts.
|
|
$conditions = '';
|
|
foreach ($postgroups as $id => $minPosts)
|
|
{
|
|
$conditions .= '
|
|
WHEN posts >= ' . $minPosts . (!empty($lastMin) ? ' AND posts <= ' . $lastMin : '') . ' THEN ' . $id;
|
|
$lastMin = $minPosts;
|
|
}
|
|
|
|
// A big fat CASE WHEN... END is faster than a zillion UPDATE's ;).
|
|
db_query("
|
|
UPDATE ${db_prefix}members
|
|
SET ID_POST_GROUP = CASE$conditions
|
|
ELSE 0
|
|
END" . ($condition != '1' ? "
|
|
WHERE $condition" : ''), __FILE__, __LINE__);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Assumes the data has been slashed.
|
|
function updateMemberData($members, $data)
|
|
{
|
|
global $db_prefix;
|
|
|
|
$setString = '';
|
|
foreach ($data as $var => $val)
|
|
{
|
|
if ($val === '+')
|
|
$val = $var . ' + 1';
|
|
elseif ($val === '-')
|
|
$val = $var . ' - 1';
|
|
|
|
$setString .= "
|
|
$var = $val,";
|
|
}
|
|
|
|
if (is_array($members))
|
|
$condition = 'ID_MEMBER IN (' . implode(', ', $members) . ')
|
|
LIMIT ' . count($members);
|
|
elseif ($members === null)
|
|
$condition = '1';
|
|
else
|
|
$condition = 'ID_MEMBER = ' . $members . '
|
|
LIMIT 1';
|
|
|
|
db_query("
|
|
UPDATE ${db_prefix}members
|
|
SET" . substr($setString, 0, -1) . '
|
|
WHERE ' . $condition, __FILE__, __LINE__);
|
|
|
|
if (isset($data['posts']))
|
|
updateStats('postgroups', $condition);
|
|
}
|
|
|
|
// Updates the settings table as well as $modSettings
|
|
// All input variables and values are assumed to have escaped apostrophes(')!
|
|
function updateSettings($changeArray)
|
|
{
|
|
global $db_prefix, $modSettings;
|
|
|
|
if (empty($changeArray) || !is_array($changeArray))
|
|
return;
|
|
|
|
$replaceArray = array();
|
|
foreach ($changeArray as $variable => $value)
|
|
{
|
|
// Don't bother if it's already like that ;).
|
|
if (isset($modSettings[$variable]) && $modSettings[$variable] == stripslashes($value))
|
|
continue;
|
|
|
|
$replaceArray[] = "('$variable', '$value')";
|
|
$modSettings[$variable] = stripslashes($value);
|
|
}
|
|
|
|
if (empty($replaceArray))
|
|
return;
|
|
|
|
db_query("
|
|
REPLACE INTO ${db_prefix}settings
|
|
(variable, value)
|
|
VALUES " . implode(',
|
|
', $replaceArray), __FILE__, __LINE__);
|
|
}
|
|
|
|
function constructAlphabetIndex($base_url)
|
|
{
|
|
$letters_ru = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ';
|
|
$letters_en = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
|
|
|
$index = '
|
|
<table width="100%">
|
|
<tr align="center">';
|
|
|
|
for ($i=0;$i<mb_strlen($letters_en);$i++) {
|
|
$index .= '
|
|
<td>
|
|
<a href="'. $base_url. ';filter='. urlencode(mb_substr($letters_en, $i,1)). '">'. mb_substr($letters_en, $i,1). '</a>
|
|
</td>';
|
|
|
|
}
|
|
|
|
$index .= '
|
|
</tr>
|
|
</table>
|
|
<table width="100%">
|
|
<tr align="center">';
|
|
for ($i=0;$i<mb_strlen($letters_ru);$i++) {
|
|
$index .= '
|
|
<td>
|
|
<a href="'. $base_url. ';filter='. urlencode(mb_substr($letters_ru, $i,1)). '">'. mb_substr($letters_ru, $i,1). '</a>
|
|
</td>';
|
|
}
|
|
|
|
$index .= '
|
|
</tr>
|
|
</table>';
|
|
|
|
return $index;
|
|
}
|
|
|
|
/* Constructs a page list.
|
|
ie. $pageindex = constructPageIndex($scripturl . '?board=' . $board, $_REQUEST['start'], $num_messages, $maxindex, true); */
|
|
function constructPageIndex($base_url, &$start, $max_value, $num_per_page, $compact_start = false, $additional = '')
|
|
{
|
|
global $modSettings;
|
|
|
|
// Save whether $start was less than 0 or not.
|
|
$start_invalid = $start < 0;
|
|
|
|
// Make sure $start is a proper variable - not less than 0.
|
|
if ($start_invalid)
|
|
$start = 0;
|
|
// Not greater than the upper bound.
|
|
elseif ($start >= $max_value)
|
|
$start = (int) $max_value - (((int) $max_value % (int) $num_per_page) == 0 ? $num_per_page : ((int) $max_value % (int) $num_per_page));
|
|
// And it has to be a multiple of $num_per_page!
|
|
else
|
|
$start = (int) $start - ((int) $start % (int) $num_per_page);
|
|
|
|
// Somehow $start ended up zero through the subtractions... fix it.
|
|
if ($start < 0)
|
|
$start = 0;
|
|
|
|
// Wireless will need the protocol on the URL somewhere.
|
|
if (WIRELESS)
|
|
{
|
|
$base_url .= ';' . WIRELESS_PROTOCOL;
|
|
$compact_start = false;
|
|
}
|
|
|
|
$base_link = '<a class="navPages" href="' . $base_url . ($compact_start ? '.' : ';start=');
|
|
|
|
// Compact pages is off or on?
|
|
if (empty($modSettings['compactTopicPagesEnable']))
|
|
{
|
|
// Show the left arrow.
|
|
$pageindex = $start == 0 ? ' ' : $base_link . ($start - $num_per_page) . ($additional == '' ? '': ';' . $additional) . '">«</a> ';
|
|
|
|
// Show all the pages.
|
|
$display_page = 1;
|
|
for ($counter = 0; $counter < $max_value; $counter += $num_per_page)
|
|
$pageindex .= $start == $counter && !$start_invalid ? $display_page++ : $base_link . $counter . ($additional == '' ? '': ';' . $additional) . '">' . $display_page++ . '</a> ';
|
|
|
|
// Show the right arrow.
|
|
$display_page = ($start + $num_per_page) > $max_value ? $max_value : ($start + $num_per_page);
|
|
if ($start != $counter - $max_value && !$start_invalid)
|
|
$pageindex .= $display_page > $counter - $num_per_page ? ' ' : $base_link . $display_page . ($additional == '' ? '': ';' . $additional) . '">»</a> ';
|
|
}
|
|
else
|
|
{
|
|
// If they didn't enter an odd value, pretend they did.
|
|
$PageContiguous = (int) ($modSettings['compactTopicPagesContiguous'] - ($modSettings['compactTopicPagesContiguous'] % 2)) / 2;
|
|
|
|
// Show the first page. (>1< ... 6 7 [8] 9 10 ... 15)
|
|
if ($start > $num_per_page * $PageContiguous)
|
|
$pageindex = $base_link . '0">1</a> ';
|
|
else
|
|
$pageindex = '';
|
|
|
|
// Show the ... after the first page. (1 >...< 6 7 [8] 9 10 ... 15)
|
|
if ($start > $num_per_page * ($PageContiguous + 1))
|
|
$pageindex .= ' ... ';
|
|
|
|
// Show the pages before the current one. (1 ... >6 7< [8] 9 10 ... 15)
|
|
for ($nCont = $PageContiguous; $nCont >= 1; $nCont--)
|
|
if ($start >= $num_per_page * $nCont)
|
|
{
|
|
$tmpStart = $start - $num_per_page * $nCont;
|
|
$pageindex.= $base_link . $tmpStart . ($additional == '' ? '': ';' . $additional) . '">' . ($tmpStart / $num_per_page + 1) . '</a> ';
|
|
}
|
|
|
|
// Show the current page. (1 ... 6 7 >[8]< 9 10 ... 15)
|
|
if (!$start_invalid)
|
|
$pageindex .= '[' . ($start / $num_per_page + 1) . '] ';
|
|
else
|
|
$pageindex .= $base_link . $start . ($additional == '' ? '': ';' . $additional) . '">' . ($start / $num_per_page + 1) . '</a> ';
|
|
|
|
// Show the pages after the current one... (1 ... 6 7 [8] >9 10< ... 15)
|
|
$tmpMaxPages = (int) (($max_value - 1) / $num_per_page) * $num_per_page;
|
|
for ($nCont = 1; $nCont <= $PageContiguous; $nCont++)
|
|
if ($start + $num_per_page * $nCont <= $tmpMaxPages)
|
|
{
|
|
$tmpStart = $start + $num_per_page * $nCont;
|
|
$pageindex .= $base_link . $tmpStart . ($additional == '' ? '': ';' . $additional) . '">' . ($tmpStart / $num_per_page + 1) . '</a> ';
|
|
}
|
|
|
|
// Show the '...' part near the end. (1 ... 6 7 [8] 9 10 >...< 15)
|
|
if ($start + $num_per_page * ($PageContiguous + 1) < $tmpMaxPages)
|
|
$pageindex .= ' ... ';
|
|
|
|
// Show the last number in the list. (1 ... 6 7 [8] 9 10 ... >15<)
|
|
if ($start + $num_per_page * $PageContiguous < $tmpMaxPages)
|
|
$pageindex .= $base_link . $tmpMaxPages . ($additional == '' ? '': ';' . $additional) . '">' . ($tmpMaxPages / $num_per_page + 1) . '</a> ';
|
|
}
|
|
|
|
return $pageindex;
|
|
}
|
|
|
|
// Formats a number to display in the style of the admin's choosing.
|
|
function comma_format($number)
|
|
{
|
|
global $modSettings;
|
|
static $thousands_separator = null, $decimal_separator = null, $decimal_count = null;
|
|
|
|
// Cache these values...
|
|
if ($decimal_separator === null)
|
|
{
|
|
// Not set for whatever reason?
|
|
if (empty($modSettings['number_format']) || preg_match('~^1([^\d]*)?234([^\d]*)(0*?)$~', $modSettings['number_format'], $matches) != 1)
|
|
return $number;
|
|
|
|
// Cache these each load...
|
|
$thousands_separator = $matches[1];
|
|
$decimal_separator = $matches[2];
|
|
$decimal_count = strlen($matches[3]);
|
|
}
|
|
|
|
// Format the string with our friend, number_format.
|
|
return number_format($number, is_float($number) ? $decimal_count : 0, $decimal_separator, $thousands_separator);
|
|
}
|
|
|
|
// Format a time to make it look purdy.
|
|
function timeformat($logTime, $show_today = true)
|
|
{
|
|
global $user_info, $txt, $db_prefix, $modSettings;
|
|
global $days, $months, $days_short, $months_short;
|
|
|
|
// Offset the time.
|
|
$time = $logTime + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600;
|
|
|
|
// We can't have a negative date!
|
|
if ($time < 0)
|
|
$time = 0;
|
|
|
|
// Today and Yesterday?
|
|
if ($modSettings['todayMod'] >= 1 && $show_today)
|
|
{
|
|
// Get the current time.
|
|
$nowtime = forum_time();
|
|
|
|
$then = @getdate($time);
|
|
$now = @getdate($nowtime);
|
|
|
|
// Try to make something of a time format string...
|
|
if (strpos($user_info['time_format'], '%H') === false && strpos($user_info['time_format'], '%T') === false)
|
|
$today_fmt = '%I:%M %p';
|
|
else
|
|
$today_fmt = '%H:%M';
|
|
|
|
// Same day of the year, same year.... Today!
|
|
if ($then['yday'] == $now['yday'] && $then['year'] == $now['year'])
|
|
return $txt['smf10'] . strftime($today_fmt, $time);
|
|
|
|
// Day-of-year is one less and same year, or it's the first of the year and that's the last of the year...
|
|
if ($modSettings['todayMod'] == '2' && (($then['yday'] == $now['yday'] - 1 && $then['year'] == $now['year']) || ($now['yday'] == 0 && $then['year'] == $now['year'] - 1) && $then['mon'] == 12 && $then['mday'] == 31))
|
|
return $txt['smf10b'] . strftime($today_fmt, $time);
|
|
}
|
|
|
|
// Strip slashes off the time format string.
|
|
/* $str = $user_info['time_format'];
|
|
|
|
if (setlocale(LC_TIME, @$txt['lang_locale']))
|
|
{
|
|
$str = preg_replace('#%a#', ucwords(strftime('%a', $time)), $str);
|
|
$str = preg_replace('#%A#', ucwords(strftime('%A', $time)), $str);
|
|
$str = preg_replace('#%b#', ucwords(strftime('%b', $time)), $str);
|
|
$str = preg_replace('#%B#', ucwords(strftime('%B', $time)), $str);
|
|
}
|
|
else
|
|
{
|
|
// Do-it-yourself time localization. Fun.
|
|
$str = preg_replace('#%a#', @$days_short[(int) strftime('%w', $time)], $str);
|
|
$str = preg_replace('#%A#', @$days[(int) strftime('%w', $time)], $str);
|
|
$str = preg_replace('#%b#', @$months_short[(int) strftime('%m', $time)], $str);
|
|
$str = preg_replace('#%B#', @$months[(int) strftime('%m', $time)], $str);
|
|
$str = preg_replace('#%p#', (strftime('%H', $time) < 12 ? 'am' : 'pm'), $str);
|
|
}
|
|
|
|
// Format any other characters..
|
|
return strftime($str, $time);
|
|
*/
|
|
$fmt = datefmt_create("ru_RU", NULL, NULL, 'Europe/Minsk', NULL, "d MMMM yyyy, HH:mm");
|
|
return str_replace(' ', ' ', datefmt_format($fmt, $time));
|
|
|
|
|
|
}
|
|
|
|
// Removes special entities from strings. Compatibility...
|
|
function un_htmlspecialchars($string)
|
|
{
|
|
return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)) + array(''' => '\'', ' ' => ' '));
|
|
}
|
|
|
|
// The current time with offset.
|
|
function forum_time($use_user_offset = true)
|
|
{
|
|
global $user_info, $modSettings;
|
|
|
|
return time() + ($modSettings['time_offset'] + ($use_user_offset ? $user_info['time_offset'] : 0)) * 3600;
|
|
}
|
|
|
|
// Parse smileys (if $enableSmileys is true) and BBC in $message.
|
|
function doUBBC($message, $enableSmileys = true, $disabledBBC = '')
|
|
{
|
|
global $txt, $modSettings, $context;
|
|
|
|
// Item codes - for <li> types. Used with [*], [@], [o], etc.
|
|
static $itemcode = array(
|
|
'[*]' => '<li>',
|
|
'[@]' => '<li type="disc">',
|
|
'[+]' => '<li type="square">',
|
|
'[x]' => '<li type="square">',
|
|
'[#]' => '<li type="square">',
|
|
'[o]' => '<li type="circle">',
|
|
'[O]' => '<li type="circle">',
|
|
'[upload]' => '<script type="text/javascript"><!--e_bgcolor = "#000000";e_text = "#ffffff";e_type = "605x55";e_lang = "en";e_id = "u:9370";//--></script><script type="text/javascript" src="http://www.easy-share.com/upload.js"></script>'
|
|
);
|
|
|
|
if (empty($modSettings['enableBBC']))
|
|
return $message;
|
|
|
|
if (substr($message, 0, 1) == ' ')
|
|
$message = ' ' . substr($message, 1);
|
|
|
|
// Rip apart code tags.
|
|
$parts = preg_split('~\[/?code\](<br />)?~', ' ' . strtr($message, array("\n" => '<br />')));
|
|
|
|
// For each part....
|
|
for ($i = 0, $n = count($parts); $i < $n; $i++)
|
|
{
|
|
// If we're outside a block... (0: outside, 1: inside, 2: outside, 3: inside, etc.)
|
|
if ($i % 2 == 0)
|
|
{
|
|
// Close the Code block, unless this is the first block. (meaning it wasn't opened yet.)
|
|
if ($i > 0)
|
|
$parts[$i] = '</div>' . $parts[$i];
|
|
|
|
|
|
// Find any [php] code tags.... CAPTURING the delimiter.
|
|
$php_parts = preg_split('~(\[php\])(?:<br />)?|(\[/php\])~', $parts[$i], -1, PREG_SPLIT_DELIM_CAPTURE);
|
|
|
|
for ($php_i = 0, $php_n = count($php_parts); $php_i < $php_n; $php_i++)
|
|
{
|
|
// Do PHP code coloring. (this is a start tag, so everything until a [/php] should be highlighted.)
|
|
if ($php_parts[$php_i] == '[php]')
|
|
{
|
|
// Get rid of the start tag.
|
|
$php_parts[$php_i] = '';
|
|
|
|
$php_string = '';
|
|
while ($php_i < count($php_parts) && $php_parts[$php_i] != '[/php]')
|
|
{
|
|
$php_string .= $php_parts[$php_i];
|
|
|
|
// This makes it easier; jut clear it out and let the implode do all the work.
|
|
$php_parts[$php_i++] = '';
|
|
}
|
|
|
|
// Highlight the PHP code, and then remove the ?php and ? we added to do so.
|
|
$php_parts[$php_i] = highlight_php_code(substr(trim($php_string), 0, 5) != '<?' ? '<?php' . $php_string . '?>' : $php_string);
|
|
if (substr(trim($php_string), 0, 5) != '<?')
|
|
$php_parts[$php_i] = preg_replace(array('~^(.+?)<\?php~', '~\?>((?:</font>)*)$~'), '$1', $php_parts[$php_i], 1);
|
|
|
|
$did_php = true;
|
|
}
|
|
else
|
|
$did_php = false;
|
|
|
|
// Parse any URLs.... have to get rid of the @ problems some things cause... stupid email addresses.
|
|
if (!empty($modSettings['autoLinkUrls']) && (strpos($php_parts[$php_i], '://') !== false || strpos($php_parts[$php_i], 'www.') !== false))
|
|
{
|
|
// Switch out quotes really quick because they can cause problems.
|
|
$php_parts[$php_i] = strtr($php_parts[$php_i], array(''' => '\'', ' ' => '\xA0', '"' => '>">', '"' => '<"<', '<' => '<lt<'));
|
|
$php_parts[$php_i] = preg_replace(array('~(?<=[\s>\.(;\'"])((?:http|https|ftp|ftps)://[\w\-_@:|]+(?:\.[\w\-_]+)*(?::\d+)?(?:/[\w\-_\~%\.@,\?&;=#+:\']*|\([\w\-_\~%\.@,\?&;=#()+:\']*)*[/\w\-_\~%@\?;=#])~i', '~(?<=[\s>(\'])(www(?:\.[\w\-_]+)+(?::\d+)?(?:/[\w\-_\~%\.@,\?&;=#+:\']*|\([\w\-_\~%\.@,\?&;=#()+:\']*)*[/\w\-_\~%@\?;=#])~i'), array('[url]$1[/url]', '[url=http://$1]$1[/url]'), $php_parts[$php_i]);
|
|
$php_parts[$php_i] = strtr($php_parts[$php_i], array('\'' => ''', '\xA0' => ' ', '>">' => '"', '<"<' => '"', '<lt<' => '<'));
|
|
}
|
|
|
|
// Parse code.....
|
|
parsecode($php_parts[$php_i],$disabledBBC);
|
|
|
|
// Parse smileys?
|
|
if (!$enableSmileys || $did_php)
|
|
continue;
|
|
|
|
// This isn't code; change any tabs to spaces.
|
|
$php_parts[$php_i] = strtr($php_parts[$php_i], array("\t" => ' '));
|
|
|
|
// Often requested but also very kludgey; break long words.
|
|
if (!empty($modSettings['fixLongWords']))
|
|
{
|
|
// This is SADLY and INCREDIBLY browser dependent.
|
|
if ($context['browser']['is_gecko'] || strpos($_SERVER['HTTP_USER_AGENT'], 'Konqueror') !== false)
|
|
$breaker = '<span style="margin: 0 -0.5ex 0 0;"> </span>';
|
|
// Opera...
|
|
elseif ($context['browser']['is_opera'])
|
|
$breaker = '<span style="margin: 0 -0.65ex 0 -1px;"> </span>';
|
|
// Internet Explorer...
|
|
else
|
|
$breaker = '<span style="width: 0; margin: 0 -0.6ex 0 -1px;"> </span>';
|
|
|
|
// The idea is, find words xx long, and then replace them with xx + space + more.
|
|
$php_parts[$php_i] = preg_replace(
|
|
'/(?<=[>;:\?\.\! \xA0\]()])(\w{' . $modSettings['fixLongWords'] . ',})/e',
|
|
"preg_replace('/(.{" . $modSettings['fixLongWords'] . "})/', '\\\$1$breaker', '\$1')",
|
|
$php_parts[$php_i]);
|
|
}
|
|
|
|
// Figure out smileys...
|
|
parsesmileys($php_parts[$php_i]);
|
|
|
|
// List items - warning they might disrupt your code...
|
|
if (empty($modSettings['disabledBBC']) || preg_match('~[\s,](list|li)[\s,]~', $modSettings['disabledBBC']) == 0)
|
|
{
|
|
$php_parts[$php_i] = strtr($php_parts[$php_i], $itemcode);
|
|
|
|
// Now do the [0], which is special and sometimes annoying.
|
|
$php_parts[$php_i] = preg_replace('~([ \t>]| )\[0\]~', '$1<li type="circle">', $php_parts[$php_i]);
|
|
}
|
|
else
|
|
$php_parts[$php_i] = str_replace(array_keys($itemcode), '<br />', $php_parts[$php_i]);
|
|
}
|
|
|
|
$parts[$i] = implode('', $php_parts);
|
|
}
|
|
// Add the Code: part.
|
|
elseif ($i <= count($parts) - 1)
|
|
{
|
|
$php_parts = preg_split('~(<\?php|\?>)~', $parts[$i], -1, PREG_SPLIT_DELIM_CAPTURE);
|
|
|
|
for ($php_i = 0, $php_n = count($php_parts); $php_i < $php_n; $php_i++)
|
|
{
|
|
// Do PHP code coloring?
|
|
if ($php_parts[$php_i] != '<?php')
|
|
continue;
|
|
|
|
$php_string = '';
|
|
while ($php_i + 1 < count($php_parts) && $php_parts[$php_i] != '?>')
|
|
{
|
|
$php_string .= $php_parts[$php_i];
|
|
$php_parts[$php_i++] = '';
|
|
}
|
|
$php_parts[$php_i] = highlight_php_code($php_string . $php_parts[$php_i]);
|
|
}
|
|
|
|
// Fix the PHP code stuff...
|
|
$parts[$i] = str_replace("<pre style=\"display: inline;\">\t</pre>", "\t", implode('', $php_parts));
|
|
|
|
// Older browsers are annoying, aren't they?
|
|
if ($context['browser']['is_ie4'] || $context['browser']['is_ie5'] || $context['browser']['is_ie5.5'])
|
|
$parts[$i] = str_replace("\t", "<pre style=\"display: inline;\">\t</pre>", $parts[$i]);
|
|
else
|
|
$parts[$i] = str_replace("\t", "<span style=\"white-space: pre;\">\t</span>", $parts[$i]);
|
|
|
|
$parts[$i] = '<div class="codeheader">' . $txt['smf238'] . ':</div><div class="code">' . $parts[$i];
|
|
}
|
|
}
|
|
$message = substr(implode('', $parts), 1);
|
|
|
|
// Fix things.
|
|
$message = strtr($message, array(' ' => ' ', "\r" => '', "\n" => '<br />'));
|
|
|
|
$message = preg_replace('~href="(https?://)((?!([-\w]+\.)*rock\.ru).*)"~iU', 'href="http://rock.ru/go/$1$2"', $message);
|
|
return $message;
|
|
}
|
|
|
|
// Parses the code in message, using the normal syntax used by some many forums...
|
|
function parsecode(&$message, $disabledBBC = '')
|
|
{
|
|
global $modSettings, $scripturl, $txt, $settings, $context;
|
|
static $codefromcache = array(), $codetocache = array();
|
|
|
|
// If it wasn't already set, set it.
|
|
if (empty($codefromcache))
|
|
{
|
|
// If any tags are disabled then we won't add them.
|
|
if (!empty($modSettings['disabledBBC']) OR !empty($disabledBBC))
|
|
{
|
|
$disabled = array_flip(array_merge(explode(',', $modSettings['disabledBBC']),explode(',', $disabledBBC)));
|
|
|
|
foreach ($disabled as $tag => $dummy)
|
|
$disabled[trim($tag)] = true;
|
|
}
|
|
|
|
$code_to_from = array(
|
|
// A named email address. [email=me@some.place.com]me[/email] And, you can't have []s in your email, I should know.
|
|
'~\[email=([^<">]+?)\](.+?)\[/email\]~ie' => isset($disabled['email']) ? '"$2 ($1)"' : '"<a href=\"mailto:" . strtr("$1", array("\"" => """, "]" => "", "[" => "")) . "\">" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\])~i", "", strtr("$2", array("@" => "@"))) . "</a>"',
|
|
// An image. Width and height can be are optional.
|
|
'~\[img(\s+width=([\d]+))?(\s+height=([\d]+))?\s*\](?:<br />)*([^<">]+?)(?:<br />)*\[/img\]~ie' => isset($disabled['img']) ? 'preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$5", array("@" => "@")))' : '"<img src=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$5", array("@" => "@", "\"" => """))) . "\" alt=\"\"" . ("$2" != "" ? " width=\"$2\"" : "") . ("$4" != "" ? " height=\"$4\"" : "") . " border=\"0\" />"',
|
|
// Find an inside link. (named?) ie. [iurl]www.simplemachines.org[/iurl]
|
|
'~\[iurl=([^<">]+?)\](.+?)\[/iurl\]~ie' => isset($disabled['iurl']) ? (!isset($disabled['url']) ? '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\" target=\"_blank\">" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[flash.*?\]|\[/flash\]|\[/iurl\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$2", array("@" => "@"))) . "</a>"' : 'preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", "$2") . " ($1)"') : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\">" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$2", array("@" => "@"))) . "</a>"',
|
|
'~\[iurl\]([^<">]+?)\[/iurl\]~ie' => isset($disabled['iurl']) ? (!isset($disabled['url']) ? '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array( "\"" => """))) . "\" target=\"_blank\">$1</a>"' : '"$1"') : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[iurl.*?\]|\[/iurl\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\">$1</a>"',
|
|
// FTP link. Named...? [ftp=upload.sourceforge.net]Sourceforge[/ftp]
|
|
'~\[ftp\]([^<">]+?)\[/ftp\]~ie' => isset($disabled['ftp']) ? 'preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", "$1")' : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\" target=\"_blank\">" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("@" => "@"))) . "</a>"',
|
|
'~\[ftp=([^<">]+?)\](.+?)\[/ftp\]~ie' => isset($disabled['ftp']) ? 'preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", "$2") . " ($1)"' : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\" target=\"_blank\">" . preg_replace("~(\[url.*?\]|\[/url\]|\[ftp.*?\]|\[/ftp\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$2", array("@" => "@"))) . "</a>"',
|
|
// Find a (named?) URL... [url]www.simplemachines.org[/url] or [url=www.simplemachines.org]SMF[/url]
|
|
'~\[url=([^:\]<">]+?)\]([^\]]*?\[url(?:=[^\]<">]+?)?\][^<">]+?\[/url\].*?)\[/url\]~ie' => isset($disabled['url']) ? 'preg_replace("~(\[url.*?\]|\[/url\])~i", "", "$2") . " ($1)"' : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\" target=\"_blank\">" . preg_replace("~(\[url.*?\]|\[/url\])~i", "", strtr("$2", array("@" => "@"))) . "</a>"',
|
|
'~\[url=([^<">]+?)\](.+?)\[/url\]~ie' => isset($disabled['url']) ? '"$2 ($1)"' : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\" target=\"_blank\">" . strtr("$2", array("@" => "@")) . "</a>"',
|
|
'~\[url\](?:<br />)*([^<">]+?)(?:<br />)*\[/url\]~ie' => isset($disabled['url']) ? '"$1"' : '"<a href=\"" . preg_replace("~(\[url.*?\]|\[/url\]|\[flash.*?\]|\[/flash\]|\[img.*?\]|\[/img\]|\[email.*?\]|\[/email\])~i", "", strtr("$1", array("\"" => """))) . "\" target=\"_blank\">$1</a>"',
|
|
// Bold, italics, underline, strikeout.
|
|
'~\[b\](.+?)\[/b\]~i' => isset($disabled['b']) ? '$1' : '<strong>$1</strong>',
|
|
'~\[i\](.+?)\[/i\]~i' => isset($disabled['i']) ? '$1' : '<em>$1</em>',
|
|
'~\[u\](.+?)\[/u\]~i' => isset($disabled['u']) ? '$1' : '<span style="text-decoration: underline;">$1</span>',
|
|
'~\[s\](.+?)\[/s\]~i' => isset($disabled['s']) ? '$1' : '<del>$1</del>',
|
|
// A quote. May or may not specify an author and/or link and date.
|
|
'~\[quote(?: author)?="(.{1,80}?)"\](?:<br />)?~i' => isset($disabled['quote']) ? '<div>' : '<div class="quoteheader">' . $txt['smf239'] . ': $1</div><blockquote class="quote">',
|
|
'~\[quote author=(.{1,80}?) link=(?:board=\d+;)?((?:topic|threadid)=[\dmsg#\./]{1,40}(?:;start=[\dmsg#\./]{1,40})?) date=(\d+)\](?:<br />)?~ei' => isset($disabled['quote']) ? '\'<div>\'' : '\'<div class="quoteheader"><a href="' . $scripturl . '?$2">' . $txt['smf239'] . '</a> <span style="font-weight:normal;">(<span class="b">$1</span> \' . timeformat(\'$3\') . \')</span></div><blockquote class="quote">\'',
|
|
'~\[quote author=(.{1,80}?)\](?:<br />)?~i' => isset($disabled['quote']) ? '<div>' : '<div class="quoteheader">' . $txt['smf239'] . ': $1</div><blockquote class="quote">',
|
|
'~\[quote\](?:<br />)?~i' => isset($disabled['quote']) ? '<div>' : '<div class="quoteheader">' . $txt['smf240'] . '</div><blockquote class="quote">',
|
|
'~\[/quote\](?:<br />)?~i' => isset($disabled['quote']) ? '</div>' : '</blockquote>',
|
|
// Size the font. [size=large]HELLO![/size]
|
|
'~\[size=([\d]{1,2}p[xt]|(?:x-)?small(?:er)?|(?:x-)?large[r]?)\](.+?)\[/size\]~i' => isset($disabled['size']) ? '$2' : '<span style="font-size: $1;">$2</span>',
|
|
'~\[size=([\d])\](.+?)\[/size\]~i' => isset($disabled['size']) ? '$2' : '<font size="$1">$2</font>',
|
|
// Performat/justify text. [center]Justifying is good.[/center]
|
|
'~\[pre\](.+?)\[/pre\]~i' => isset($disabled['pre']) ? '$1' : '<pre>$1</pre>',
|
|
'~\[left\](.+?)\[/left\]~i' => isset($disabled['left']) ? '$1' : '<div align="left">$1</div>',
|
|
'~\[right\](.+?)\[/right\]~i' => isset($disabled['right']) ? '$1' : '<div align="right">$1</div>',
|
|
'~\[center\](.+?)\[/center\]~i' => isset($disabled['center']) ? '$1' : '<span style="display: block; text-align: center;">$1</span>',
|
|
// Teletyped text. Monospace, in other words.
|
|
'~\[tt\](.+?)\[/tt\]~i' => isset($disabled['tt']) ? '$1' : '<tt>$1</tt>',
|
|
// Subscript and superscript. 6[sup]2[/sup] = 36.
|
|
'~\[sub\](.+?)\[/sub\]~i' => isset($disabled['sub']) ? '$1' : '<sub>$1</sub>',
|
|
'~\[sup\](.+?)\[/sup\]~i' => isset($disabled['sup']) ? '$1' : '<sup>$1</sup>',
|
|
// An email address. [email]me@some.place.com[/email]
|
|
'~\[email\](?:<br />)*(.+?)(?:<br />)*\[/email\]~ie' => isset($disabled['email']) ? '"$1"' : '"<a href=\"mailto:" . strtr("$1", array("\"" => """, "[" => "", "]" => "")) . "\">$1</a>"',
|
|
// Specify a specific font. [font=Comic Sans]Blah![/font]
|
|
'~\[font=([\w,\-\s]+?)\](.+?)\[/font\]~i' => isset($disabled['font']) ? '$2' : '<span style="font-family: $1;">$2</span>',
|
|
// Colors.... [red]See?[/red]
|
|
'~\[color=(#[\da-fA-F]{3}|#[\da-fA-F]{6}|[\w]{1,12})\](.*?)\[/color\]~i' => isset($disabled['color']) ? '$2' : '<span style="color: $1;">$2</span>',
|
|
'~\[(black|white|red|green|blue)\](.+?)\[/\1\]~i' => isset($disabled['color']) ? '$2' : '<span style="color: $1;">$2</span>',
|
|
'~\[(chr|k)issy\](.+?)\[/\1issy\]~i' => isset($disabled['color']) ? '$2' : '<span style="color: #CC0099;">$2 :-*</span>',
|
|
// Lists... [list][*]First, ...[o]Second![li]THIRD!!![/li][/list]
|
|
'~\[list\](?:<br />)?~i' => isset($disabled['list']) || isset($disabled['li']) ? '' : '<ul style="margin-top: 0; margin-bottom: 0;">',
|
|
'~\[/list\](?:<br />)?~i' => isset($disabled['list']) || isset($disabled['li']) ? '' : '</ul>',
|
|
'~(?:<br />| |\s)*\[li\](.+?)\[/li\](?:<br />| |\s)*~i' => isset($disabled['list']) || isset($disabled['li']) ? '<br />$1<br />' : '<li>$1</li>',
|
|
// Horizontal rule. [hr] => ------------------.
|
|
'~\[hr(?:\s*/)?\]~i' => isset($disabled['hr']) ? '' : '<hr />',
|
|
// A break. [br] or [br /]. (it makes no sense to disable this one :P.)
|
|
'~\[br(?:\s*/)?\]~i' => '<br />',
|
|
// Right-to-left and left-to-right strings.
|
|
'~\[(ltr|rtl)\](.+?)\[/\1\]~i' => isset($disabled['ltr']) || isset($disabled['rtl']) ? '$2' : '<div dir="$1">$2</div>',
|
|
// Acronyms and abbreviations... [acronym=Bulletin Board Code]BBC[/acronym]
|
|
'~\[abbr=((?:")?)(.+?)\\1\](.+?)\[/abbr\]~ie' => isset($disabled['abbr']) ? '"$3 ($2)"' : '"<abbr title=\"" . strtr("$2", array("\"" => """)) . "\">$3</abbr>"',
|
|
'~\[acronym=((?:")?)(.+?)\\1\](.+?)\[/acronym\]~ie' => isset($disabled['acronym']) ? '"$3 ($2)"' : '"<acronym title=\"" . strtr("$2", array("\"" => """)) . "\">$3</acronym>"',
|
|
// [me=Comment]does something[/me]
|
|
'~\[me=((?:")?)(.{1,80}?)\\1\](.+?)\[/me\](?:<br />)?~i' => isset($disabled['ftp']) ? '/me $3<br />' : '<div class="meaction">* $2 $3</div>',
|
|
// An email address they just typed in. Don't match if there's already a mailto: or = before it.
|
|
'~(?<=[\?\s\xA0[\]()*\\\;>]|^)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?,\s\xA0\[\]()*\\\]|$|<br />| |>|<|"|'|\.(?:\.| |\s|$|<br />))~i' => '<a href="mailto:$1">$1</a>',
|
|
'~(?<=<br />)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?\.,\s\xA0\[\]()*\\\]|$|<br />| |>|<|"|')~i' => '<a href="mailto:$1">$1</a>',
|
|
// This last one fixes spaces at the beginning of lines.
|
|
'~<br /> ~' => '<br /> ',
|
|
// Match a table... hopefully with everything in the right place.
|
|
'~\[table\](?:\s|\xA0|<br />| )*((?:\[tr\](?:\s|\xA0|<br />| )*\[td\]).*?(?:(?:\s|\xA0|<br />| )*\[/td\]\[/tr\])*)(?:\s|\xA0|<br />| )*\[/table\](?:\s|\xA0|<br />| )?~i' => '<table>$1</table>',
|
|
);
|
|
|
|
$codefromcache = array_keys($code_to_from);
|
|
$codetocache = array_values($code_to_from);
|
|
|
|
// GLOWING or /shadowed/ text.
|
|
$codefromcache[] = '~\[glow=([#\w]{3,12}),([012]\d{1,2}|\d{1,2})(,[^]]+)?\](.+?)\[/glow\]~i';
|
|
$codetocache[] = isset($disabled['glow']) ? '$4' : '<table border="0" cellpadding="0" cellspacing="0" style="display: inline; vertical-align: middle; font: inherit;"><tr><td style="filter: Glow(color=$1, strength=$2); font: inherit;">$4</td></tr></table> ';
|
|
$codefromcache[] = '~\[shadow=([#\w]{3,12}),(left|right|top|bottom|[0123]\d{0,2})\](.+?)\[/shadow\]~ei';
|
|
$codetocache[] = isset($disabled['shadow']) ? 'strtr(\'$3\', array(\'\\"\' => \'"\'))' : '\'<table border="0" cellpadding="0" cellspacing="0" style="display: inline; vertical-align: middle; font: inherit;"><tr><td style="filter: Shadow(color=$1, direction=\' . (isset($shadow_directions[\'$2\']) ? $shadow_directions[\'$2\'] : (int) \'$2\') . \'); font: inherit;">\' . strtr(\'$3\', array(\'\\"\' => \'"\')) . \'</td></tr></table> \'';
|
|
|
|
// Moving text... [move]stuff[/move]
|
|
$codefromcache[] = '~\[move\](.+?)\[/move\]~i';
|
|
$codetocache[] = isset($disabled['move']) ? '$1' : '<marquee>$1</marquee>';
|
|
|
|
// Handle flash.
|
|
$codefromcache[] = '~\[flash=(\d+),(\d+)\](?:<br />)*([^<>]+?)(?:<br />)*\[/flash\]~ie';
|
|
if (empty($modSettings['enableEmbeddedFlash']) || isset($disabled['flash']))
|
|
$codetocache[] = isset($disabled['url']) ? '"$3"' : '"<a href=\"" . strtr("$3", array("\"" => """)) . "\" target=\"_blank\">$3</a>"';
|
|
// Internet Explorer for Windows.
|
|
elseif ($context['browser']['is_ie'] && !$context['browser']['is_mac_ie'])
|
|
$codetocache[] = '"<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\"$1\" height=\"$2\"><param name=\"movie\" value=\"" . strtr("$3", array("\"" => """)) . "\" /><param name=\"play\" value=\"true\" /><param name=\"loop\" value=\"true\" /><param name=\"quality\" value=\"high\" /><param name=\"AllowScriptAccess\" value=\"never\" /><embed src=\"" . strtr("$3", array("\"" => """)) . "\" width=\"$1\" height=\"$2\" play=\"true\" loop=\"true\" quality=\"high\" AllowScriptAccess=\"never\" /><noembed><a href=\"" . strtr("$3", array("\"" => """)) . "\" target=\"_blank\">$3</a></noembed></object>"';
|
|
// Anything else.
|
|
else
|
|
$codetocache[] = '"<embed type=\"application/x-shockwave-flash\" src=\"" . strtr("$3", array("\"" => """)) . "\" width=\"$1\" height=\"$2\" play=\"true\" loop=\"true\" quality=\"high\" AllowScriptAccess=\"never\" /><noembed><a href=\"" . strtr("$3", array("\"" => """)) . "\" target=\"_blank\">$3</a></noembed>"';
|
|
}
|
|
|
|
// Nothing to parse... ?
|
|
if (!strstr($message, '[') && !strstr($message, '://') && !strstr($message, '@') && !strstr($message, '/me') && !strstr($message, '<'))
|
|
return;
|
|
|
|
$message = strtr($message, array('$' => '$'));
|
|
|
|
// Replace <a href="something">somewhere</a> with HTML.
|
|
if (!empty($modSettings['enablePostHTML']) && strstr($message, '<'))
|
|
{
|
|
$message = preg_replace('~<a\s+href=(?:")?(?:\[url\])?((?:http://|ftp:/\|https://|ftps://|mailto:).+?)(?:\[/url\])?(?:")?>(.+?)</a>~ie', '\'<a href="$1">\' . preg_replace(\'~(\[url.*?\]|\[/url\])~\', \'\', \'$2\') . \'</a>\'', $message);
|
|
|
|
// Do <img ... /> - with security... action= -> action-.
|
|
preg_match_all('~<img\s+src=(?:")?(?:\[url\])?((?:http://|ftp://|https://|ftps://).+?)(?:\[/url\])?(?:")?(?:\s+alt=(?:")?(.*?)(?:")?)?(?:\s?/)?>~i', $message, $matches, PREG_PATTERN_ORDER);
|
|
if (!empty($matches[0]))
|
|
{
|
|
$replaces = array();
|
|
foreach ($matches[1] as $match => $imgtag)
|
|
{
|
|
// No alt?
|
|
if (!isset($matches[2][$match]))
|
|
$matches[2][$match] = '';
|
|
|
|
// Remove action= from the URL - no funny business, now.
|
|
if ($imgtag != preg_replace('~action(=|%3d)(?!dlattach)~i', 'action-', $imgtag))
|
|
$replaces[$matches[0][$match]] = '<img src="' . preg_replace('~action(=|%3d)(?!dlattach)~i', 'action-', $imgtag) . '" alt="' . $matches[2][$match] . '" border="0" />';
|
|
|
|
// Check if the image is larger than allowed.
|
|
if (!empty($modSettings['maxwidth']) && !empty($modSettings['maxheight']))
|
|
{
|
|
list ($width, $height) = url_image_size($imgtag);
|
|
|
|
if ($width > $modSettings['maxwidth'] || $height > $modSettings['maxheight'])
|
|
{
|
|
if ($width > $modSettings['maxwidth'] && !empty($modSettings['maxwidth']))
|
|
{
|
|
$height = floor($modSettings['maxwidth'] / $width * $height);
|
|
$width = $modSettings['maxwidth'];
|
|
if ($height > $modSettings['maxheight'] && !empty($modSettings['maxheight']))
|
|
{
|
|
$width = floor($modSettings['maxheight'] / $height * $width);
|
|
$height = $modSettings['maxheight'];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ($height > $modSettings['maxheight'] && !empty($modSettings['maxheight']))
|
|
{
|
|
$width = floor($modSettings['maxheight'] / $height * $width);
|
|
$height = $modSettings['maxheight'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the new image tag.
|
|
$replaces[$matches[0][$match]] = '<img src="' . preg_replace('~action(=|%3d)(?!dlattach)~i', 'action-', $imgtag) . '" width="' . $width . '" height="' . $height . '" alt="' . $matches[2][$match] . '" border="0" />';
|
|
}
|
|
elseif (strpos($matches[0][$match], '[url]') !== false || substr($matches[0][$match], 0, 4) == '<')
|
|
$replaces[$matches[0][$match]] = '<img src="' . preg_replace('~action(=|%3d)(?!dlattach)~i', 'action-', $imgtag) . '" alt="' . $matches[2][$match] . '" border="0" />';
|
|
}
|
|
|
|
$message = strtr($message, $replaces);
|
|
}
|
|
}
|
|
|
|
// Do the code if necessary.
|
|
if (strstr($message, '[') || strstr($message, '://') || strstr($message, '@') || strstr($message, '/me'))
|
|
{
|
|
$shadow_directions = array('left' => '270', 'right' => '90', 'top' => '0', 'bottom' => '180');
|
|
|
|
$message = preg_replace($codefromcache, $codetocache, $message);
|
|
$message = preg_replace_callback('#\[video\](.+?)\[/video\]#', 'parseVideo', $message);
|
|
|
|
// Tables need to be done twice or they won't work properly.
|
|
if (strpos($message, '<table>') !== false)
|
|
{
|
|
for ($i = 0; $i < 2; $i++)
|
|
$message = preg_replace(
|
|
array(
|
|
'~((?:<table>|</tr>|\[/tr\])(?:\s|\xA0|<br />| )*(?:<tr>|\[tr\])|</td>|\[/td\])(?:\s|\xA0|<br />| )*\[td\](?:\s|\xA0|<br />| )*(.*?)(?:\s|\xA0|<br />| )*\[/td\](?:\s|\xA0|<br />| )*((?:</tr>|\[/tr\])(?:\s|\xA0|<br />| )*(?:<tr>|\[tr\]|</table>)|<td(?: valign="top")?>|\[td\])~i',
|
|
'~(<table>|</tr>|\[/tr\])(?:\s|\xA0|<br />| )*\[tr\](?:\s|\xA0|<br />| )*(.*?)(?:\s|\xA0|<br />| )*\[/tr\](?:\s|\xA0|<br />| )*(</table>|<tr>|\[tr\])~i'
|
|
),
|
|
array(
|
|
'$1<td valign="top">$2</td>$3',
|
|
'$1<tr>$2</tr>$3'
|
|
), $message
|
|
);
|
|
}
|
|
}
|
|
|
|
// Enable Basic HTML?
|
|
if (!empty($modSettings['enablePostHTML']) && strstr($message, '<'))
|
|
{
|
|
// b, u, i, s, pre... basic tags.
|
|
$closable_tags = array('b', 'u', 'i', 's', 'pre', 'blockquote');
|
|
foreach ($closable_tags as $tag)
|
|
{
|
|
$opens = substr_count($message, '<' . $tag . '>');
|
|
$closes = substr_count($message, '</' . $tag . '>');
|
|
$message = str_replace(array('<' . $tag . '>', '</' . $tag . '>'), array('<' . $tag . '>', '</' . $tag . '>'), $message);
|
|
|
|
if ($closes < $opens)
|
|
$message .= str_repeat('</' . $tag . '>', $opens - $closes);
|
|
}
|
|
|
|
// <br /> should be empty.
|
|
$empty_tags = array('br');
|
|
foreach ($empty_tags as $tag)
|
|
$message = str_replace(array('<' . $tag . '>', '<' . $tag . '/>', '<' . $tag . ' />'), '<' . $tag . ' />', $message);
|
|
}
|
|
}
|
|
|
|
function parseVideo($matches) {
|
|
list ($url) = explode('#', $matches[1]);
|
|
|
|
// check if it's a vimeo video
|
|
if (preg_match('~^(https?://)?(www\.)?vimeo\.com/\d+?~', $url)) {
|
|
return parseVideoVimeo($url);
|
|
} elseif (preg_match('~^(https?://)?(www\.)?youtube\.com~', $url)) {
|
|
return parseVideoYoutube($url);
|
|
} elseif (preg_match('~^(https?://)?vids.myspace.com/~', $url)) {
|
|
return parseVideoMyspace($url);
|
|
} elseif (preg_match('~^(https?://)?(www\.)?dailymotion\.com/video/~', $url)) {
|
|
return parseVideoDailymotion($url);
|
|
} else {
|
|
return $matches[1];
|
|
}
|
|
}
|
|
|
|
function parseVideoMyspace($url)
|
|
{
|
|
$ttl = 3600;
|
|
$html = xcache_get($url);
|
|
if ($html !== NULL) {
|
|
return $html;
|
|
}
|
|
$page = curl_get(htmlspecialchars_decode($url));
|
|
$matches = array ();
|
|
preg_match('~link type="text/xml\+oembed" href="(.+)"~imsU', $page, $matches);
|
|
if (! empty ($matches)) {
|
|
$xml_url = $matches[1];#.'&maxheight=360';
|
|
$html = getVideoOEmbed($xml_url);
|
|
} else {
|
|
$html = false;
|
|
}
|
|
|
|
if ($html == false) {
|
|
$html = '<a href="'.$url.'">Посмотреть видео</a>';
|
|
$ttl = 60;
|
|
}
|
|
xcache_set($url, $html, $ttl);
|
|
return $html;
|
|
}
|
|
|
|
function parseVideoDailymotion($url)
|
|
{
|
|
$ttl = 3600;
|
|
$html = xcache_get($url);
|
|
if ($html !== NULL) {
|
|
return $html;
|
|
}
|
|
$oembed_endpoint = 'http://www.dailymotion.com/api/oembed';
|
|
// Create the URLs
|
|
$xml_url = $oembed_endpoint.'?url='.rawurlencode($url).
|
|
'&format=xml';
|
|
$html = getVideoOEmbed($xml_url);
|
|
if ($html == false) {
|
|
$html = '<a href="'.$url.'">Посмотреть видео</a>';
|
|
$ttl = 60;
|
|
}
|
|
xcache_set($url, $html, $ttl);
|
|
return $html;
|
|
}
|
|
|
|
#function xcache_get($param) {
|
|
# return NULL;
|
|
#}
|
|
#
|
|
#function xcache_set($param, $value) {
|
|
# return NULL;
|
|
#}
|
|
function parseVideoYoutube($url)
|
|
{
|
|
$ttl = 3600;
|
|
$html = xcache_get($url);
|
|
if ($html !== NULL) {
|
|
return $html;
|
|
}
|
|
$oembed_endpoint = 'http://www.youtube.com/oembed';
|
|
$_q = array ();
|
|
$q = parse_url($url, PHP_URL_QUERY);
|
|
parse_str($q, $_q);
|
|
$theURL = "http://www.youtube.com/watch?".$q; #v=".$_q['v'];
|
|
// Create the URLs
|
|
$xml_url = $oembed_endpoint.'?url='.rawurlencode($theURL).
|
|
'&format=xml';
|
|
#&maxwidth=640&maxheight=360';
|
|
$html = getVideoOEmbed($xml_url);
|
|
if ($html == false) {
|
|
$html = '<a href="'.$theURL.'">Посмотреть видео</a>';
|
|
$ttl = 60;
|
|
}
|
|
xcache_set($url, $html, $ttl);
|
|
return $html;
|
|
}
|
|
|
|
function parseVideoVimeo($url)
|
|
{
|
|
$ttl = 3600;
|
|
$html = xcache_get($url);
|
|
if ($html !== NULL) {
|
|
return $html;
|
|
}
|
|
$oembed_endpoint = 'http://www.vimeo.com/api/oembed';
|
|
// Create the URLs
|
|
$xml_url = $oembed_endpoint.'.xml?url='.rawurlencode($url).
|
|
'&maxwidth=640&maxheight=360';
|
|
$html = getVideoOEmbed($xml_url);
|
|
if ($html == false) {
|
|
$html = '<a href="'.$url.'">Посмотреть видео</a>';
|
|
$ttl = 60;
|
|
}
|
|
xcache_set($url, $html, $ttl);
|
|
return $html;
|
|
}
|
|
|
|
function getVideoOEmbed($xml_url)
|
|
{
|
|
// Load in the oEmbed XML
|
|
$xml = curl_get($xml_url);
|
|
if ($xml !== FALSE && $oembed = @simplexml_load_string($xml)) {
|
|
return html_entity_decode($oembed->html);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Curl helper function
|
|
function curl_get($url) {
|
|
$curl = curl_init($url);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
|
curl_setopt($curl, CURLOPT_TIMEOUT, 5);
|
|
curl_setopt($curl, CURLOPT_FAILONERROR, 1);
|
|
$return = curl_exec($curl);
|
|
curl_close($curl);
|
|
return $return;
|
|
}
|
|
|
|
|
|
// Parse smileys in the passed message.
|
|
function parsesmileys(&$message)
|
|
{
|
|
global $modSettings, $db_prefix, $txt, $user_info;
|
|
static $smileyfromcache = array(), $smileytocache = array();
|
|
|
|
// If the smiley array hasn't been set, do it now.
|
|
if (empty($smileyfromcache) && $user_info['smiley_set'] != 'none')
|
|
{
|
|
// Use the default smileys if it is disabled. (better for "portability" of smileys.)
|
|
if (empty($modSettings['smiley_enable']))
|
|
{
|
|
$smileysfrom = array('>:D', ':D', '::)', '>:(', ':)', ';)', ';D', ':(', ':o', '8)', ':P', '???', ':-[', ':-X', ':-*', ':\'(', ':-\\', '^-^', 'O0', 'C:-)', '0:)');
|
|
$smileysto = array('evil.gif', 'cheesy.gif', 'rolleyes.gif', 'angry.gif', 'smiley.gif', 'wink.gif', 'grin.gif', 'sad.gif', 'shocked.gif', 'cool.gif', 'tongue.gif', 'huh.gif', 'embarassed.gif', 'lipsrsealed.gif', 'kiss.gif', 'cry.gif', 'undecided.gif', 'azn.gif', 'afro.gif', 'police.gif', 'angel.gif');
|
|
$smileysdescs = array('', $txt[289], $txt[450], $txt[288], $txt[287], $txt[292], $txt[293], $txt[291], $txt[294], $txt[295], $txt[451], $txt[296], $txt[526], $txt[527], $txt[529], $txt[530], $txt[528], '', '', '', '');
|
|
}
|
|
else
|
|
{
|
|
// Load the smileys in reverse order by length so they don't get parsed wrong.
|
|
$result = db_query("
|
|
SELECT code, filename, description
|
|
FROM ${db_prefix}smileys
|
|
ORDER BY LENGTH(code) DESC", __FILE__, __LINE__);
|
|
$smileysfrom = array();
|
|
$smileysto = array();
|
|
$smileysdescs = array();
|
|
while ($row = mysql_fetch_assoc($result))
|
|
{
|
|
$smileysfrom[] = $row['code'];
|
|
$smileysto[] = $row['filename'];
|
|
$smileysdescs[] = $row['description'];
|
|
}
|
|
mysql_free_result($result);
|
|
}
|
|
|
|
// This smiley regex makes sure it doesn't parse smileys within code tags (so [url=mailto:David@bla.com] doesn't parse the :D smiley)
|
|
for ($i = 0, $n = count($smileysfrom); $i < $n; $i++)
|
|
{
|
|
#$smileyfromcache[] = '/(?<=[>:\?\.\s\xA0[\]()*\\\;])(' . preg_quote($smileysfrom[$i], '/') . '|' . preg_quote(htmlspecialchars($smileysfrom[$i], ENT_QUOTES), '/') . ')(?=[^[:alpha:]0-9]|$)/';
|
|
$smileyfromcache[] = '/(' . preg_quote($smileysfrom[$i], '/') . '|' . preg_quote(htmlspecialchars($smileysfrom[$i], ENT_QUOTES), '/') . ')(?=[^[:alpha:]0-9]|$)/';
|
|
$smileytocache[] = '<img src="' . $modSettings['smileys_url'] . '/' . $user_info['smiley_set'] . '/' . $smileysto[$i] . '" alt="' . htmlspecialchars($smileysdescs[$i]) . '" border="0" />';
|
|
}
|
|
}
|
|
|
|
// Replace away! (do it twice just in case.)
|
|
$message = preg_replace($smileyfromcache, $smileytocache, $message);
|
|
}
|
|
|
|
// Highlight any code...
|
|
function highlight_php_code($code)
|
|
{
|
|
global $context;
|
|
|
|
// Remove special characters.
|
|
$code = un_htmlspecialchars(strtr($code, array('<br />' => "\n", "\t" => 'SMF_TAB();')));
|
|
|
|
$oldlevel = error_reporting(0);
|
|
|
|
// It's easier in 4.2.x+.
|
|
if ((float) PHP_VERSION < 4.2)
|
|
{
|
|
ob_start();
|
|
@highlight_string($code);
|
|
$buffer = str_replace(array("\n", "\r"), '', ob_get_contents());
|
|
ob_end_clean();
|
|
}
|
|
else
|
|
$buffer = str_replace(array("\n", "\r"), '', @highlight_string($code, true));
|
|
|
|
error_reporting($oldlevel);
|
|
|
|
// Yes, I know this is kludging it, but this is the best way to preserve tabs from PHP :P.
|
|
$buffer = preg_replace('~SMF_TAB(</(font|span)><(font color|span style)="[^"]*?">)?\(\);~', "<pre style=\"display: inline;\">\t</pre>", $buffer);
|
|
|
|
return strtr($buffer, array('\'' => ''', '<code>' => '', '</code>' => ''));
|
|
}
|
|
|
|
// Put this user in the online log.
|
|
function writeLog($force = false)
|
|
{
|
|
global $db_prefix, $ID_MEMBER, $user_info, $sc, $modSettings;
|
|
|
|
// Don't mark them as online more than every so often.
|
|
if (empty($_SESSION['log_time']) || $_SESSION['log_time'] < (time() - 8) || $force)
|
|
$_SESSION['log_time'] = time();
|
|
else
|
|
return;
|
|
|
|
if (!empty($modSettings['who_enabled']))
|
|
{
|
|
$serialized = $_GET + array('USER_AGENT' => $_SERVER['HTTP_USER_AGENT']);
|
|
unset($serialized['sesc']);
|
|
$serialized = addslashes(serialize($serialized));
|
|
}
|
|
else
|
|
$serialized = '';
|
|
|
|
// Guests use 0, members use their session ID.
|
|
$session_id = $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id();
|
|
$ip = ip2long($user_info['ip']);
|
|
|
|
db_query("
|
|
DELETE FROM ${db_prefix}log_online
|
|
WHERE logTime < NOW() - INTERVAL " . ($modSettings['lastActive'] * 60) . " SECOND
|
|
OR session = '$session_id'" . (empty($ID_MEMBER) ? '' : " OR ID_MEMBER = $ID_MEMBER"), __FILE__, __LINE__);
|
|
db_query("
|
|
INSERT IGNORE INTO ${db_prefix}log_online
|
|
(session, ID_MEMBER, ip, url)
|
|
VALUES ('${session_id}', '${ID_MEMBER}', '${ip}', '${serialized}')", __FILE__, __LINE__);
|
|
|
|
// Well, they are online now.
|
|
if (empty($_SESSION['timeOnlineUpdated']))
|
|
$_SESSION['timeOnlineUpdated'] = time();
|
|
|
|
// Set their login time, if not already done within the last minute.
|
|
if (!empty($user_info['last_login']) && $user_info['last_login'] < time() - 60)
|
|
{
|
|
// Don't count longer than 15 minutes.
|
|
if (time() - $_SESSION['timeOnlineUpdated'] > 60 * 15)
|
|
$_SESSION['timeOnlineUpdated'] = time();
|
|
|
|
updateMemberData($ID_MEMBER, array('lastLogin' => time(), 'memberIP' => '\'' . $user_info['ip'] . '\'', 'totalTimeLoggedIn' => 'totalTimeLoggedIn + ' . (time() - $_SESSION['timeOnlineUpdated'])));
|
|
|
|
$user_info['total_time_logged_in'] += time() - $_SESSION['timeOnlineUpdated'];
|
|
$_SESSION['timeOnlineUpdated'] = time();
|
|
}
|
|
}
|
|
|
|
/* Make sure the browser doesn't come back and repost the form data.
|
|
Should be used whenever anything is posted. */
|
|
function redirectexit($setLocation = '', $add = true, $refresh = false)
|
|
{
|
|
global $scripturl, $modSettings;
|
|
|
|
// Add the scripturl on if needed.
|
|
if (WIRELESS)
|
|
{
|
|
if ($add)
|
|
$setLocation = $scripturl . '?' . $setLocation;
|
|
|
|
$char = strpos($setLocation, '?') === false ? '?' : ';';
|
|
|
|
if (strpos($setLocation, '#') ==! false)
|
|
$setLocation = strtr($setLocation, array('#' => $char . WIRELESS_PROTOCOL . '#'));
|
|
else
|
|
$setLocation .= $char . WIRELESS_PROTOCOL;
|
|
}
|
|
elseif ($add)
|
|
$setLocation = $scripturl . ($setLocation != '' ? '?' . $setLocation : '');
|
|
|
|
// Put the session ID in.
|
|
if (defined('SID') && SID != '')
|
|
$setLocation = preg_replace('/' . preg_quote($scripturl, '/') . '(?!\?' . preg_quote(SID, '/') . ')(\?)?/', $scripturl . '?' . SID . '&', $setLocation);
|
|
|
|
// Send the header only.
|
|
if (empty($modSettings['redirectMetaRefresh']))
|
|
{
|
|
// We send a Refresh header only in special cases because Location looks better. (and is quicker...)
|
|
if ($refresh)
|
|
header('Refresh: 0; URL=' . strtr($setLocation, array(' ' => '%20', ';' => '%3b')));
|
|
else
|
|
header('Location: ' . str_replace(' ', '%20', $setLocation));
|
|
}
|
|
else
|
|
{
|
|
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="refresh" content="0;URL=', strtr($setLocation, array(' ' => '%20', ';' => '%3b')), '" />
|
|
</head>
|
|
<body style="font-family: Georgia, serif; font-size: 1.3em; margin-top: 20%; text-align: center; background-color: white;">
|
|
<a href="', str_replace(' ', '%20', $setLocation), '" style="color: black;">', $setLocation, '</a>
|
|
</body>
|
|
</html>';
|
|
}
|
|
|
|
obExit(false);
|
|
}
|
|
|
|
// Ends execution. Takes care of template loading and remembering the previous URL.
|
|
function obExit($do_header = null, $do_footer = null, $from_index = false)
|
|
{
|
|
global $context, $modSettings;
|
|
static $header_done = false;
|
|
|
|
// Clear out the stat cache.
|
|
trackStats();
|
|
|
|
if ($do_header === null)
|
|
$do_header = !$header_done;
|
|
if ($do_footer === null)
|
|
$do_footer = $do_header;
|
|
|
|
// Has the template/header been done yet?
|
|
if ($do_header)
|
|
{
|
|
// Start up the session URL fixer.
|
|
#ob_start('ob_sessrewrite');
|
|
|
|
// Display the screen in the logical order.
|
|
template_header();
|
|
$header_done = true;
|
|
}
|
|
if ($do_footer)
|
|
{
|
|
// Just show the footer, then.
|
|
loadSubTemplate(isset($context['sub_template']) ? $context['sub_template'] : 'main');
|
|
template_footer();
|
|
|
|
// (since this is just debugging... it's okay that it's after </html>.)
|
|
db_debug_junk();
|
|
}
|
|
|
|
// Remember this URL in case someone doesn't like sending HTTP_REFERER.
|
|
$_SESSION['old_url'] = $_SERVER['REQUEST_URI'];
|
|
|
|
// For session check verfication.... don't switch browsers...
|
|
$_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
|
|
|
|
// Don't exit if we're coming from index.php; that will pass through normally.
|
|
if (!$from_index || WIRELESS)
|
|
exit;
|
|
}
|
|
|
|
// Set up the administration sections.
|
|
function adminIndex($area)
|
|
{
|
|
global $txt, $context, $scripturl, $sc, $modSettings, $user_info, $settings;
|
|
|
|
// Load the language and templates....
|
|
loadLanguage('Admin');
|
|
loadTemplate('Admin');
|
|
|
|
// Admin area 'Forum Controls'.
|
|
$context['admin_areas']['forum'] = array(
|
|
'title' => $txt[427],
|
|
'areas' => array(
|
|
'index' => '<a href="' . $scripturl . '?action=admin">' . $txt[208] . '</a>',
|
|
'credits' => '<a href="' . $scripturl . '?action=admin;credits">' . $txt['support_credits_title'] . '</a>',
|
|
)
|
|
);
|
|
|
|
if (allowedTo('edit_news'))
|
|
$context['admin_areas']['forum']['areas']['edit_news'] = '<a href="' . $scripturl . '?action=editnews">' . $txt[7] . '</a>';
|
|
|
|
if (allowedTo('manage_boards'))
|
|
$context['admin_areas']['forum']['areas']['manage_boards'] = '<a href="' . $scripturl . '?action=manageboards">' . $txt[4] . '</a>';
|
|
|
|
if (allowedTo('admin_forum'))
|
|
$context['admin_areas']['forum']['areas']['manage_packages'] = '<a href="' . $scripturl . '?action=packages">' . $txt['package1'] . '</a>';
|
|
|
|
if (allowedTo('manage_attachments'))
|
|
$context['admin_areas']['forum']['areas']['manage_attachments'] = '<a href="' . $scripturl . '?action=manageattachments">' . $txt['smf201'] . '</a>';
|
|
|
|
// Admin area 'Forum Configuration'.
|
|
if (allowedTo(array('manage_smileys', 'admin_forum', 'moderate_forum')))
|
|
{
|
|
$context['admin_areas']['config'] = array(
|
|
'title' => $txt[428],
|
|
'areas' => array()
|
|
);
|
|
|
|
if (allowedTo('admin_forum'))
|
|
{
|
|
$context['admin_areas']['config']['areas']['edit_mods_settings'] = '<a href="' . $scripturl . '?action=modifyModSettings">' . $txt['modSettings_title'] . '</a>';
|
|
$context['admin_areas']['config']['areas']['edit_settings'] = '<a href="' . $scripturl . '?action=modsettings;sesc=' . $sc . '">' . $txt[222] . '</a>';
|
|
$context['admin_areas']['config']['areas']['edit_theme_settings'] = '<a href="' . $scripturl . '?action=theme;sa=settings;id=' . $settings['theme_id'] . ';sesc=' . $sc . '">' . $txt['theme_current_settings'] . '</a>';
|
|
$context['admin_areas']['config']['areas']['manage_themes'] = '<a href="' . $scripturl . '?action=theme;sa=admin;sesc=' . $sc . '">' . $txt['theme_admin'] . '</a>';
|
|
}
|
|
|
|
if (allowedTo('manage_smileys'))
|
|
$context['admin_areas']['config']['areas']['manage_smileys'] = '<a href="' . $scripturl . '?action=smileys">' . $txt['smileys_manage'] . '</a>';
|
|
|
|
if (allowedTo('moderate_forum'))
|
|
{
|
|
$context['admin_areas']['config']['areas']['edit_censored'] = '<a href="' . $scripturl . '?action=setcensor">' . $txt[135] . '</a>';
|
|
$context['admin_areas']['config']['areas']['edit_agreement'] = '<a href="' . $scripturl . '?action=editagreement">' . $txt['smf11'] . '</a>';
|
|
}
|
|
}
|
|
|
|
// Admin area 'Member Controls'.
|
|
if (allowedTo(array('moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'manage_permissions')))
|
|
{
|
|
$context['admin_areas']['members'] = array(
|
|
'title' => $txt[426],
|
|
'areas' => array()
|
|
);
|
|
|
|
if (allowedTo('manage_membergroups'))
|
|
$context['admin_areas']['members']['areas']['edit_groups'] = '<a href="' . $scripturl . '?action=membergroups;">' . $txt[8] . '</a>';
|
|
|
|
if (allowedTo('manage_permissions'))
|
|
$context['admin_areas']['members']['areas']['edit_permissions'] = '<a href="' . $scripturl . '?action=permissions">' . $txt['edit_permissions'] . '</a>';
|
|
|
|
if (allowedTo('moderate_forum'))
|
|
{
|
|
$context['admin_areas']['members']['areas']['registration_center'] = '<a href="' . $scripturl . '?action=regcenter">' . (!empty($modSettings['registration_method']) && $modSettings['registration_method'] != 3 ? $txt['registration_center'] : $txt['registration_member']) . '</a>';
|
|
$context['admin_areas']['members']['areas']['view_members'] = '<a href="' . $scripturl . '?action=viewmembers">' . $txt[5] . '</a>';
|
|
$context['admin_areas']['members']['areas']['edit_reserved_names'] = '<a href="' . $scripturl . '?action=setreserve">' . $txt[207] . '</a>';
|
|
$context['admin_areas']['members']['areas']['warning_manager'] = '<a href="' . $scripturl . '?action=warnlist">' . $txt['visual_warning_management'] . '</a>';
|
|
$context['admin_areas']['members']['areas']['postmod_manager'] = '<a href="' . $scripturl . '?action=warnpmman">' . $txt['visual_postmod_manager'] . '</a>';
|
|
}
|
|
|
|
if (allowedTo('send_mail'))
|
|
$context['admin_areas']['members']['areas']['email_members'] = '<a href="' . $scripturl . '?action=mailing">' . $txt[6] . '</a>';
|
|
|
|
if (allowedTo('manage_bans'))
|
|
$context['admin_areas']['members']['areas']['ban_members'] = '<a href="' . $scripturl . '?action=ban">' . $txt['ban_title'] . '</a>';
|
|
}
|
|
|
|
// Admin area 'Maintenance Controls'.
|
|
if (allowedTo('admin_forum'))
|
|
{
|
|
$context['admin_areas']['maintenance'] = array(
|
|
'title' => $txt[501],
|
|
'areas' => array(
|
|
'maintain_forum' => '<a href="' . $scripturl . '?action=maintain">' . $txt['maintain_title'] . '</a>',
|
|
'view_errors' => '<a href="' . $scripturl . '?action=viewErrorLog">' . $txt['errlog1'] . '</a>'
|
|
)
|
|
);
|
|
|
|
if (!empty($modSettings['modlog_enabled']))
|
|
$context['admin_areas']['maintenance']['areas']['view_moderation_log'] = '<a href="' . $scripturl . '?action=modlog">' . $txt['modlog_view'] . '</a>';
|
|
}
|
|
|
|
// Make sure the administrator has a valid session...
|
|
validateSession();
|
|
|
|
// Figure out which one we're in now...
|
|
foreach ($context['admin_areas'] as $id => $section)
|
|
if (isset($section[$area]))
|
|
$context['admin_section'] = $id;
|
|
$context['admin_area'] = $area;
|
|
|
|
// obExit will know what to do!
|
|
$context['template_layers'][] = 'admin';
|
|
}
|
|
|
|
// Usage: logAction('remove', array('starter' => $ID_MEMBER_STARTED));
|
|
function logAction($action, $extra = array())
|
|
{
|
|
global $db_prefix, $ID_MEMBER, $modSettings, $user_info;
|
|
|
|
if (!empty($modSettings['modlog_enabled']))
|
|
{
|
|
db_query("
|
|
INSERT INTO ${db_prefix}log_actions
|
|
(logTime, ID_MEMBER, IP, action, extra)
|
|
VALUES (" . time() . ", $ID_MEMBER, '$user_info[ip]', '$action',
|
|
'" . addslashes(serialize($extra)) . "')", __FILE__, __LINE__);
|
|
|
|
return db_insert_id();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Track Statistics.
|
|
function trackStats($stats = array())
|
|
{
|
|
global $db_prefix, $modSettings;
|
|
static $cache_stats = array();
|
|
|
|
if (empty($modSettings['trackStats']))
|
|
return false;
|
|
if (!empty($stats))
|
|
return $cache_stats = array_merge($cache_stats, $stats);
|
|
elseif (empty($cache_stats))
|
|
return false;
|
|
|
|
$setStringUpdate = '';
|
|
foreach ($cache_stats as $field => $change)
|
|
{
|
|
$setStringUpdate .= '
|
|
' . $field . ' = ' . ($change === '+' ? $field . ' + 1' : $change) . ',';
|
|
|
|
if ($change === '+')
|
|
$cache_stats[$field] = 1;
|
|
}
|
|
|
|
$date = strftime('%Y%m%d', forum_time(false));
|
|
db_query("
|
|
UPDATE ${db_prefix}log_activity
|
|
SET" . substr($setStringUpdate, 0, -1) . "
|
|
WHERE date = $date
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
if (db_affected_rows() == 0)
|
|
{
|
|
db_query("
|
|
INSERT IGNORE INTO ${db_prefix}log_activity
|
|
(date, " . implode(', ', array_keys($cache_stats)) . ")
|
|
VALUES ($date, " . implode(', ', $cache_stats) . ')', __FILE__, __LINE__);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Make sure the user isn't posting over and over again.
|
|
function spamProtection($error_type)
|
|
{
|
|
global $modSettings, $txt, $db_prefix, $user_info;
|
|
|
|
// Delete old entries... if you can moderate this board or this is login, override spamWaitTime with 2.
|
|
if ($error_type == 'spam' && !allowedTo('moderate_board'))
|
|
db_query("
|
|
DELETE FROM ${db_prefix}log_floodcontrol
|
|
WHERE logTime < " . (time() - $modSettings['spamWaitTime']), __FILE__, __LINE__);
|
|
else
|
|
db_query("
|
|
DELETE FROM ${db_prefix}log_floodcontrol
|
|
WHERE (logTime < " . (time() - 2) . " AND ip = '$user_info[ip]')
|
|
OR logTime < " . (time() - $modSettings['spamWaitTime']), __FILE__, __LINE__);
|
|
|
|
// Add a new entry, deleting the old if necessary.
|
|
db_query("
|
|
REPLACE INTO ${db_prefix}log_floodcontrol
|
|
(ip, logTime)
|
|
VALUES ('$user_info[ip]', " . time() . ")", __FILE__, __LINE__);
|
|
// If affected is 0 or 2, it was there already.
|
|
if (db_affected_rows() != 1)
|
|
{
|
|
// Spammer! You only have to wait a *few* seconds!
|
|
fatal_lang_error($error_type . 'WaitTime_broken', false, array($modSettings['spamWaitTime']));
|
|
return true;
|
|
}
|
|
|
|
// They haven't posted within the limit.
|
|
return false;
|
|
}
|
|
|
|
// Get the size of a specified image with better error handling.
|
|
function url_image_size($url)
|
|
{
|
|
// Get the host to pester...
|
|
preg_match('~^\w+://(.+?)/(.*)$~', $url, $match);
|
|
|
|
// Can't figure it out, just try the image size.
|
|
if ($url == '' || $url == 'http://' || $url == 'https://')
|
|
return false;
|
|
elseif (!isset($match[1]))
|
|
return @getimagesize($url);
|
|
|
|
// Try to connect to the server... give it one full second.
|
|
$temp = 0;
|
|
$fp = @fsockopen($match[1], 80, $temp, $temp, 1);
|
|
|
|
// Successful? Continue...
|
|
if ($fp != false)
|
|
{
|
|
// Send the HEAD request.
|
|
fwrite($fp, 'HEAD /' . $match[2] . ' HTTP/1.1' . "\r\n" . 'Connection: close' . "\r\n" . 'Host: ' . $match[1] . "\r\n\r\n");
|
|
// Read in the HTTP/1.1 or whatever.
|
|
$test = substr(fgets($fp, 11), -1);
|
|
fclose($fp);
|
|
|
|
// See if it returned a 404/403 or something.
|
|
if ($test < 4)
|
|
return @getimagesize($url);
|
|
}
|
|
|
|
// Didn't work.
|
|
return false;
|
|
}
|
|
|
|
function determineTopicClass(&$topic_context)
|
|
{
|
|
// Set topic class depending on locked status and number of replies.
|
|
if ($topic_context['is_very_hot'])
|
|
$topic_context['class'] = 'veryhot';
|
|
elseif ($topic_context['is_hot'])
|
|
$topic_context['class'] = 'hot';
|
|
else
|
|
$topic_context['class'] = 'normal';
|
|
|
|
$topic_context['class'] .= $topic_context['is_poll'] ? '_poll' : '_post';
|
|
|
|
if ($topic_context['is_locked'])
|
|
$topic_context['class'] .= '_locked';
|
|
|
|
if ($topic_context['is_sticky'])
|
|
$topic_context['class'] .= '_sticky';
|
|
|
|
// This is so old themes will still work.
|
|
$topic_context['extended_class'] = &$topic_context['class'];
|
|
}
|
|
|
|
// Sets up the basic theme context stuff.
|
|
function setupThemeContext()
|
|
{
|
|
global $modSettings, $user_info, $scripturl, $context, $settings, $options, $txt, $maintenance;
|
|
global $db_prefix; // Grudge's Mod
|
|
|
|
// Get some news...
|
|
$context['news_lines'] = explode("\n", str_replace("\r", '', trim(addslashes($modSettings['news']))));
|
|
$context['fader_news_lines'] = array();
|
|
for ($i = 0, $n = count($context['news_lines']); $i < $n; $i++)
|
|
{
|
|
if (trim($context['news_lines'][$i]) == '')
|
|
continue;
|
|
|
|
// Clean it up for presentation ;).
|
|
$context['news_lines'][$i] = doUBBC(stripslashes(trim($context['news_lines'][$i])));
|
|
|
|
// Gotta be special for the javascript.
|
|
$context['fader_news_lines'][$i] = strtr(addslashes($context['news_lines'][$i]), array('/' => '\/', '<a href=' => '<a hre" + "f='));
|
|
}
|
|
$context['random_news_line'] = $context['news_lines'][rand(0, count($context['news_lines']) - 1)];
|
|
|
|
if (!$user_info['is_guest'])
|
|
{
|
|
$context['user']['messages'] = &$user_info['messages'];
|
|
$context['user']['unread_messages'] = &$user_info['unread_messages'];
|
|
if (allowedTo('visual_approve_any'))
|
|
{
|
|
$result = db_query("
|
|
SELECT COUNT(*)
|
|
FROM ${db_prefix}postmoderation", __FILE__, __LINE__);
|
|
list($modmsg) = mysql_fetch_row($result);
|
|
if ($modmsg)
|
|
$context['user']['awaiting_mod'] = $modmsg . ' ' . $txt['visual_require_mod'];
|
|
}
|
|
|
|
// Personal message popup...
|
|
if ($user_info['unread_messages'] > (isset($_SESSION['unread_messages']) ? $_SESSION['unread_messages'] : 0))
|
|
$context['user']['popup_messages'] = true;
|
|
else
|
|
$context['user']['popup_messages'] = false;
|
|
$_SESSION['unread_messages'] = $user_info['unread_messages'];
|
|
|
|
if (allowedTo('moderate_forum'))
|
|
$context['unapproved_members'] = !empty($modSettings['registration_method']) && $modSettings['registration_method'] == 2 ? $modSettings['unapprovedMembers'] : 0;
|
|
|
|
$context['user']['avatar'] = array();
|
|
|
|
// Figure out the avatar... uploaded?
|
|
if ($user_info['avatar']['url'] == '')
|
|
{
|
|
// If they are allowed to use an uploaded avatar.
|
|
if (!empty($user_info['avatar']['ID_ATTACH']) && !empty($modSettings['avatar_allow_upload']))
|
|
{
|
|
$__avatar = glob('attachments/avatar_'.$context['user']['id'].'.{jpg,png,gif}', GLOB_BRACE);
|
|
if (!empty($__avatar)) $__avatar = $__avatar[0];
|
|
$context['user']['avatar']['href'] = 'http://img.rock.ru/forum/'.$__avatar;
|
|
}
|
|
}
|
|
// Full URL?
|
|
elseif (substr($user_info['avatar']['url'], 0, 7) == 'http://' && !empty($modSettings['avatar_allow_external_url']))
|
|
{
|
|
$context['user']['avatar']['href'] = $user_info['avatar']['url'];
|
|
if ($modSettings['avatar_action_too_large'] == 'option_html_resize')
|
|
{
|
|
if (!empty($modSettings['avatar_max_width_external']))
|
|
$context['user']['avatar']['width'] = $modSettings['avatar_max_width_external'];
|
|
if (!empty($modSettings['avatar_max_height_external']))
|
|
$context['user']['avatar']['height'] = $modSettings['avatar_max_height_external'];
|
|
}
|
|
}
|
|
// Server stored?
|
|
elseif (!empty($modSettings['avatar_allow_server_stored']))
|
|
$context['user']['avatar']['href'] = $modSettings['avatar_url'] . '/' . htmlspecialchars($user_info['avatar']['url']);
|
|
|
|
if (!empty($context['user']['avatar']))
|
|
$context['user']['avatar']['image'] = '<img src="' . $context['user']['avatar']['href'] . '"' . (isset($context['user']['avatar']['width']) ? ' width="' . $context['user']['avatar']['width'] . '"' : '') . (isset($context['user']['avatar']['height']) ? ' height="' . $context['user']['avatar']['height'] . '"' : '') . ' alt="" border="0" />';
|
|
|
|
// Figure out how long they've been logged in.
|
|
$context['user']['total_time_logged_in'] = array(
|
|
'days' => floor($user_info['total_time_logged_in'] / 86400),
|
|
'hours' => floor(($user_info['total_time_logged_in'] % 86400) / 3600),
|
|
'minutes' => floor(($user_info['total_time_logged_in'] % 3600) / 60)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$context['user']['messages'] = 0;
|
|
$context['user']['unread_messages'] = 0;
|
|
$context['user']['avatar'] = array();
|
|
$context['user']['total_time_logged_in'] = array('days' => 0, 'hours' => 0, 'minutes' => 0);
|
|
$context['user']['popup_messages'] = false;
|
|
|
|
if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1)
|
|
$txt['welcome_guest'] .= $txt['welcome_guest_activate'];
|
|
}
|
|
|
|
// Set up the menu privileges.
|
|
$context['allow_search'] = allowedTo('search_posts');
|
|
$context['allow_admin'] = allowedTo(array('admin_forum', 'manage_boards', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_attachments', 'manage_smileys'));
|
|
$context['allow_edit_profile'] = !$user_info['is_guest'] && allowedTo(array('profile_view_own', 'profile_view_any', 'profile_identity_own', 'profile_identity_any', 'profile_extra_own', 'profile_extra_any', 'profile_remove_own', 'profile_remove_any', 'moderate_forum', 'manage_membergroups'));
|
|
$context['allow_calendar'] = allowedTo('calendar_view') && !empty($modSettings['cal_enabled']);
|
|
|
|
$context['allow_pm'] = allowedTo('pm_read');
|
|
|
|
$context['in_maintenance'] = !empty($maintenance);
|
|
$context['current_time'] = timeformat(time(), false);
|
|
$context['show_vBlogin'] = !empty($modSettings['enableVBStyleLogin']) && $user_info['is_guest'];
|
|
|
|
// This is here because old index templates might still use it.
|
|
$context['show_news'] = !empty($settings['enable_news']);
|
|
|
|
// This is done to make it easier to add to all themes...
|
|
if ($context['user']['popup_messages'] && !empty($options['popup_messages']))
|
|
{
|
|
$context['html_headers'] .= '
|
|
<script language="JavaScript" type="text/javascript"><!--
|
|
if (confirm("' . $txt['show_personal_messages'] . '"))
|
|
window.open("' . $scripturl . '?action=pm");
|
|
// --></script>';
|
|
}
|
|
|
|
if (!isset($context['page_title']))
|
|
$context['page_title'] = '';
|
|
}
|
|
|
|
// This is the only template included in the sources...
|
|
function template_rawdata()
|
|
{
|
|
global $context;
|
|
|
|
echo $context['raw_data'];
|
|
}
|
|
|
|
function template_header()
|
|
{
|
|
global $txt, $modSettings, $context, $settings, $user_info;
|
|
|
|
setupThemeContext();
|
|
|
|
// Print stuff to prevent caching of pages.
|
|
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
|
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
|
|
|
foreach ($context['template_layers'] as $layer)
|
|
{
|
|
loadSubTemplate($layer . '_above', true);
|
|
|
|
// May seem contrived, but this is done in case the main layer isn't there...
|
|
if ($layer == 'main' && allowedTo('admin_forum'))
|
|
{
|
|
$securityFiles = array('install.php', 'upgrade.php', 'repair_paths.php', 'repair_settings.php');
|
|
foreach ($securityFiles as $i => $securityFile)
|
|
{
|
|
if (!file_exists($securityFile))
|
|
unset($securityFiles[$i]);
|
|
}
|
|
|
|
if (!empty($securityFiles))
|
|
{
|
|
echo '
|
|
<div class="windowbg" style="margin: 2ex; padding: 2ex; border: 2px dashed red; color: red;">
|
|
<span style="text-decoration: underline;">', $txt['smf299'], '</span>
|
|
<div style="padding-left: 4ex;">';
|
|
|
|
foreach ($securityFiles as $securityFile)
|
|
echo '
|
|
', $txt['smf300'], $securityFile, '!<br />';
|
|
|
|
echo '
|
|
</div>
|
|
</div>';
|
|
}
|
|
}
|
|
// If the user is banned from posting inform them of it.
|
|
elseif ($layer == 'main' && !empty($_SESSION['ban']['cannot_post']['is_banned']))
|
|
{
|
|
echo '
|
|
<div class="windowbg" style="margin: 2ex; padding: 2ex; border: 2px dashed red; color: red;">
|
|
', sprintf($txt['you_are_post_banned'], $user_info['is_guest'] ? $txt[28] : $user_info['name']);
|
|
|
|
// The substr here is used to get rid of the first of two <br />s.
|
|
if (isset($_SESSION['ban']['cannot_post']['reason']))
|
|
echo '
|
|
<div style="padding-left: 4ex;">', substr($_SESSION['ban']['cannot_post']['reason'], 6), '</div>';
|
|
|
|
echo '
|
|
</div>';
|
|
}
|
|
}
|
|
|
|
if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template']))
|
|
{
|
|
$settings['theme_url'] = $settings['default_theme_url'];
|
|
$settings['images_url'] = $settings['default_images_url'];
|
|
$settings['theme_dir'] = $settings['default_theme_dir'];
|
|
}
|
|
}
|
|
|
|
// Show the copyright...
|
|
function theme_copyright($get_it = false)
|
|
{
|
|
global $forum_copyright, $context, $boardurl, $forum_version, $txt;
|
|
static $found = false;
|
|
|
|
// Meaning, this is the footer checking in..
|
|
if ($get_it === true)
|
|
return $found;
|
|
|
|
echo '
|
|
<span class="smalltext" style="display: inline; visibility: visible; font-family: Verdana, Arial, sans-serif;">';
|
|
|
|
if ($get_it == 'none')
|
|
{
|
|
$found = true;
|
|
echo '
|
|
The administrator doesn\'t want a copyright notice saying this is copyright 2001-2005 by <a href="http://www.lewismedia.com/" target="_blank">Lewis Media</a>, and named <a href="http://www.simplemachines.org/">SMF</a>, so the forum will honor this request.';
|
|
}
|
|
// If it's in the copyright, and we are outputting it... it's been found.
|
|
elseif ((strpos($forum_copyright, '<a href="http://www.simplemachines.org/" onclick="this.href += \'referer.php?forum=' . urlencode($context['forum_name'] . '|' . $boardurl . '|' . $forum_version) . '\';" target="_blank">SMF') !== false || strpos($forum_copyright, '<a href="http://www.simplemachines.org/" target="_blank">SMF') !== false || strpos($forum_copyright, '<a href="http://www.simplemachines.org/" title="Simple Machines Forum" target="_blank">SMF') !== false) && (strpos($forum_copyright, '<a href="http://www.lewismedia.com/">Lewis Media</a>') !== false || strpos($forum_copyright, '<a href="http://www.lewismedia.com/" target="_blank">Lewis Media</a>') !== false))
|
|
{
|
|
$found = true;
|
|
echo $forum_copyright;
|
|
}
|
|
|
|
echo '
|
|
</span>';
|
|
}
|
|
|
|
function template_footer()
|
|
{
|
|
global $context, $settings, $modSettings, $time_start, $db_count;
|
|
|
|
// Show the load time? (only makes sense for the footer.)
|
|
$context['show_load_time'] = $modSettings['timeLoadPageEnable'] == 1;
|
|
$time_start = explode(' ', $time_start);
|
|
$time_end = explode(' ', microtime());
|
|
$context['load_time'] = round($time_end[0] + $time_end[1] - $time_start[0] - $time_start[1], 3);
|
|
$context['load_queries'] = $db_count;
|
|
|
|
if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template']))
|
|
{
|
|
$settings['theme_url'] = $settings['actual_theme_url'];
|
|
$settings['images_url'] = $settings['actual_images_url'];
|
|
$settings['theme_dir'] = $settings['actual_theme_dir'];
|
|
}
|
|
|
|
foreach (array_reverse($context['template_layers']) as $layer)
|
|
loadSubTemplate($layer . '_below', true);
|
|
|
|
// Do not remove hard-coded text - it's in here so users cannot change the text easily. (as if it were in language file)
|
|
if (!theme_copyright(true) && !empty($context['template_layers']) && SMF !== 'SSI' && !WIRELESS)
|
|
{
|
|
echo '
|
|
<div align="center" style="display: block !important; visibility: visible !important; font-size: xx-large !important; font-weight: bold; color: black !important; background-color: white !important;">
|
|
Sorry, the copyright must be in the template.<br />
|
|
Please notify this ' . "forum's" . ' administrator that this site is using an <span style="color: #FF0000;">ILLEGAL</span> copy of <a href="http://www.simplemachines.org/" style="color: black !important; font-size: xx-large !important;">SMF</a>!
|
|
</div>';
|
|
|
|
log_error('Copyright removed!!');
|
|
}
|
|
}
|
|
|
|
// Debugging.
|
|
function db_debug_junk()
|
|
{
|
|
global $db_cache, $db_count, $context, $scripturl;
|
|
|
|
// Add to Settings.php if you want to show the debugging information.
|
|
if (!isset($GLOBALS['db_show_debug']) || $GLOBALS['db_show_debug'] !== true || (isset($_GET['action']) && $_GET['action'] == 'viewquery'))
|
|
return;
|
|
|
|
if (empty($_SESSION['view_queries']))
|
|
$_SESSION['view_queries'] = 0;
|
|
|
|
$_SESSION['debug'] = $db_cache;
|
|
echo '
|
|
<div align="left" class="smalltext">', (isset($context['template']) ? '
|
|
Template: <i>' . $context['template'] . '</i>' . (isset($context['sub_template']) ? ' (<i>' . $context['sub_template'] . '</i>)' : '') . '.<br />' : ''), '
|
|
<a href="', $scripturl, '?action=viewquery" target="_blank">Queries used: ', $db_count, '</a>.<br />
|
|
<br />';
|
|
|
|
if ($_SESSION['view_queries'] == 1)
|
|
foreach ($db_cache as $q => $qq)
|
|
echo '
|
|
', substr(trim($qq['q']), 0, 6) == 'SELECT' ? '<a class="b" href="' . $scripturl . '?action=viewquery;qq=' . ($q + 1) . '#qq' . $q . '" target="_blank">' : '', nl2br(str_replace("\t", ' ', ltrim($qq['q'], "\n\r"))) . '</a> in <em>' . $qq['f'] . '</em> line <em>' . $qq['l'] . '</em>, which took ' . $qq['t'] . ' seconds.<br />
|
|
<br />';
|
|
|
|
echo '
|
|
<a href="' . $scripturl . '?action=viewquery;sa=hide">[' . (empty($_SESSION['view_queries']) ? 'show' : 'hide') . ' queries]</a>
|
|
</div>';
|
|
}
|
|
|
|
// Get an attachment's encrypted filename. If $new is true, won't check for file existence.
|
|
function getAttachmentFilename($filename, $attachment_id, $new = false)
|
|
{
|
|
global $modSettings;
|
|
|
|
// Remove special accented characters - ie. s?.
|
|
$clean_name = strtr($filename, '????????????????????????????????????????????????????????????', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy');
|
|
$clean_name = strtr($clean_name, array('?' => 'TH', '?' => 'th', '?' => 'DH', '?' => 'dh', '?' => 'ss', '?' => 'OE', '?' => 'oe', '?' => 'AE', '?' => 'ae', '?' => 'u'));
|
|
|
|
// Sorry, no spaces, dots, or anything else but letters allowed.
|
|
$clean_name = preg_replace(array('/\s/', '/[^\w_\.\-]/'), array('_', ''), $clean_name);
|
|
|
|
$enc_name = $attachment_id . '_' . str_replace('.', '_', $clean_name) . md5($clean_name);
|
|
$clean_name = preg_replace('~\.[\.]+~', '.', $clean_name);
|
|
|
|
if ($attachment_id == false || ($new && empty($modSettings['attachmentEncryptFilenames'])))
|
|
return $clean_name;
|
|
elseif ($new)
|
|
return $enc_name;
|
|
|
|
if (file_exists($modSettings['attachmentUploadDir'] . '/' . $enc_name))
|
|
$filename = $modSettings['attachmentUploadDir'] . '/' . $enc_name;
|
|
else
|
|
$filename = $modSettings['attachmentUploadDir'] . '/' . $clean_name;
|
|
|
|
return $filename;
|
|
}
|
|
|
|
function getThumbnailFilename($filename, $attachment_id, $new = false)
|
|
{
|
|
global $modSettings;
|
|
/*
|
|
// Remove special accented characters - ie. s?.
|
|
$clean_name = strtr($filename, '????????????????????????????????????????????????????????????', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy');
|
|
$clean_name = strtr($clean_name, array('?' => 'TH', '?' => 'th', '?' => 'DH', '?' => 'dh', '?' => 'ss', '?' => 'OE', '?' => 'oe', '?' => 'AE', '?' => 'ae', '?' => 'u'));
|
|
|
|
// Sorry, no spaces, dots, or anything else but letters allowed.
|
|
$clean_name = preg_replace(array('/\s/', '/[^\w_\.\-]/'), array('_', ''), $clean_name);
|
|
|
|
$enc_name = $attachment_id . '_' . str_replace('.', '_', $clean_name) . md5($clean_name);
|
|
$clean_name = preg_replace('~\.[\.]+~', '.', $clean_name);
|
|
|
|
if ($attachment_id == false || ($new && empty($modSettings['attachmentEncryptFilenames'])))
|
|
return $clean_name;
|
|
elseif ($new)
|
|
return $enc_name;
|
|
|
|
if (file_exists($modSettings['attachmentUploadDir'] . '/thumbs/' . $enc_name))
|
|
$filename = $modSettings['attachmentUploadDir'] . '/thumbs/' . $enc_name;
|
|
else
|
|
$filename = $modSettings['attachmentUploadDir'] . '/thumbs/' . $clean_name;
|
|
|
|
return $filename;*/
|
|
return $modSettings['attachmentUploadDir']."/thumbs/".$attachment_id.md5($filename);
|
|
}
|
|
|
|
function ob_googlebot_getAgent( &$user_agent, &$user_name, &$result, $guest )
|
|
{
|
|
//Search Spiders
|
|
$spider_agents = array (
|
|
array (
|
|
'agent' => 'WISENutbot',
|
|
'spidername' => 'Looksmart spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'MSNBot',
|
|
'spidername' => 'MSN spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'W3C_Validator',
|
|
'spidername' => 'W3C Validator',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Googlebot-Image',
|
|
'spidername' => 'Google-Image Spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Googlebot',
|
|
'spidername' => 'Google spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Mediapartners-Google',
|
|
'spidername' => 'Google AdSense spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Scooter',
|
|
'spidername' => 'Altavista spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Yahoo! Slurp',
|
|
'spidername' => 'Yahoo spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Yandex',
|
|
'spidername' => 'YandexBot',
|
|
'spider' => true
|
|
),
|
|
array (
|
|
'agent' => 'Rambler',
|
|
'spidername' => 'RamblerBot',
|
|
'spider' => true
|
|
),
|
|
array (
|
|
'agent' => 'FAST-WebCrawler',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Wget',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Ask Jeeves',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Speedy Spider',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'SurveyBot',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'IBM_Planetwide',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'GigaBot',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'ia_archiver',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'FAST-WebCrawler',
|
|
'spider' => true,
|
|
),
|
|
array (
|
|
'agent' => 'Inktomi Slurp',
|
|
'spider' => true,
|
|
),
|
|
);
|
|
|
|
foreach( $spider_agents as $poss )
|
|
if (strpos(strtolower($user_agent), strtolower($poss['agent'])) !== false)
|
|
{
|
|
if ( $guest && isset($poss['spider']) && $poss['spider'] )
|
|
$user_name = isset($poss['spidername']) ? $poss['spidername'] : (isset($poss['name']) ? $poss['name'] : $poss['agent']);
|
|
|
|
$result = isset($poss['name']) ? $poss['name'] : $poss['agent'];
|
|
return isset($poss['spider']) && $poss['spider'];
|
|
}
|
|
|
|
$result = $user_agent;
|
|
return false;
|
|
};
|
|
|
|
?>
|