<?php
/**
* Main function library.
*
* @package Cotonti
* @version 0.6.25
* @author Neocrome, Cotonti Team
* @copyright Copyright (c) 2008-2011 Cotonti Team
* @license BSD License
*/
defined('SED_CODE') or die('Wrong URL');
// System requirements check
(function_exists('version_compare') && version_compare(PHP_VERSION, '5.1.0', '>='))
or die('Cotonti system requirements: PHP 5.1 or above.');
extension_loaded('mbstring')
or die('Cotonti system requirements: mbstring PHP extension must be loaded.');
// Group constants
define('SED_GROUP_GUESTS', 1);
define('SED_GROUP_INACTIVE', 2);
define('SED_GROUP_BANNED', 3);
define('SED_GROUP_MEMBERS', 4);
define('SED_GROUP_TOPADMINS', 5);
/* ======== Pre-sets ========= */
$out = array();
$plu = array();
$sys = array();
$usr = array();
$i = explode(' ', microtime());
$sys['starttime'] = $i[1] + $i[0];
//unset ($warnings, $moremetas, $morejavascript, $error_string, $sed_cat, $sed_smilies, $sed_acc, $sed_catacc, $sed_rights, $sed_config, $sql_config, $sed_usersonline, $sed_plugins, $sed_groups, $rsedition, $rseditiop, $rseditios, $tcount, $qcount)
$cfg['svnrevision'] = '$Rev$'; //DO NOT MODIFY this is set by SVN automatically
$cfg['version'] = '0.6.25';
$cfg['dbversion'] = '0.6.25';
if($cfg['customfuncs'])
{
require_once $cfg['system_dir'] . '/functions.custom.php';
}
// Set default file permissions if not present in config
if (!isset($cfg['file_perms']))
{
$cfg['file_perms'] = 0664;
}
if (!isset($cfg['dir_perms']))
{
$cfg['dir_perms'] = 0777;
}
/**
* Registry for hash functions
*/
$sed_hash_funcs = array('md5', 'sha1', 'sha256');
/**
* Strips everything but alphanumeric, hyphens and underscores
*
* @param string $text Input
* @return string
*/
function sed_alphaonly($text)
{
return(preg_replace('/[^a-zA-Z0-9\-_]/', '', $text));
}
// For compatibility with PHP < 5.2
if(PHP_VERSION < '5.2.0')
{
function mb_stripos($haystack, $needle, $offset = 0)
{
return stripos($haystack, $needle, $offset);
}
function mb_stristr($haystack, $needle)
{
return stristr($haystack, $needle);
}
function mb_strripos($haystack, $needle, $offset = 0)
{
return strripos($haystack, $needle, $offset);
}
function mb_strstr($haystack, $needle)
{
return strstr($haystack, $needle);
}
}
/*
* ================================= Authorization Subsystem ==================================
*/
/**
* Returns specific access permissions
*
* @param string $area Seditio area
* @param string $option Option to access
* @param string $mask Access mask
* @return mixed
*/
function sed_auth($area, $option, $mask = 'RWA')
{
global $sys, $usr;
$mn['R'] = 1;
$mn['W'] = 2;
$mn['1'] = 4;
$mn['2'] = 8;
$mn['3'] = 16;
$mn['4'] = 32;
$mn['5'] = 64;
$mn['A'] = 128;
$masks = str_split($mask);
$res = array();
foreach($masks as $k => $ml)
{
if(empty($mn[$ml]))
{
$sys['auth_log'][] = $area . '.' . $option . '.' . $ml . '=0';
$res[] = FALSE;
}
elseif ($option == 'any')
{
$cnt = 0;
if(is_array($usr['auth'][$area]))
{
foreach($usr['auth'][$area] as $k => $g)
{
$cnt += (($g & $mn[$ml]) == $mn[$ml]);
}
}
$cnt = ($cnt == 0 && $usr['auth']['admin']['a'] && $ml == 'A') ? 1 : $cnt;
$sys['auth_log'][] = ($cnt > 0) ? $area . '.' . $option . '.' . $ml . '=1'
: $area . '.' . $option . '.' . $ml . '=0';
$res[] = ($cnt > 0) ? TRUE : FALSE;
}
else
{
$sys['auth_log'][] = (($usr['auth'][$area][$option] & $mn[$ml]) == $mn[$ml]) ?
$area . '.' . $option . '.' . $ml . '=1' : $area . '.' . $option . '.' . $ml . '=0';
$res[] = (($usr['auth'][$area][$option] & $mn[$ml]) == $mn[$ml]) ? TRUE : FALSE;
}
}
return (count($res) == 1) ? $res[0] : $res;
}
/**
* Builds Access Control List (ACL) for a specific user
*
* @param int $userid User ID
* @param int $maingrp User main group
* @return array
*/
function sed_auth_build($userid, $maingrp=0)
{
global $db_auth, $db_groups_users;
$groups = array();
$authgrid = array();
$tmpgrid = array();
if ($userid==0 || $maingrp==0)
{
$groups[] = 1;
}
else
{
$groups[] = $maingrp;
$sql = sed_sql_query("SELECT gru_groupid FROM $db_groups_users WHERE gru_userid=$userid");
while ($row = sed_sql_fetcharray($sql))
{
$groups[] = $row['gru_groupid'];
}
}
$sql_groups = implode(',', $groups);
$sql = sed_sql_query("SELECT auth_code, auth_option, auth_rights FROM $db_auth WHERE auth_groupid IN (".$sql_groups.") ORDER BY auth_code ASC, auth_option ASC");
while ($row = sed_sql_fetcharray($sql))
{
$authgrid[$row['auth_code']][$row['auth_option']] |= $row['auth_rights'];
}
return $authgrid;
}
/**
* Clears user permissions cache
*
* @param mixed $id User ID or 'all'
* @return int
*/
function sed_auth_clear($id='all')
{
global $db_users;
if($id=='all')
{
$sql = sed_sql_query("UPDATE $db_users SET user_auth='' WHERE 1");
}
else
{
$sql = sed_sql_query("UPDATE $db_users SET user_auth='' WHERE user_id='$id'");
}
return sed_sql_affectedrows();
}
/**
* Block user if he is not allowed to access the page
*
* @param bool $allowed Authorization result
* @return bool
*/
function sed_block($allowed)
{
if(!$allowed)
{
global $sys;
sed_redirect(sed_url('message', 'msg=930&' . $sys['url_redirect'], '', true));
exit;
}
return FALSE;
}
/**
* Block guests from viewing the page
*
* @return bool
*/
function sed_blockguests()
{
global $usr, $sys;
if ($usr['id']<1)
{
header('Location: ' . SED_ABSOLUTE_URL . sed_url('message', 'msg=930&' . $sys['url_redirect'], '', true));
exit;
}
return FALSE;
}
/*
* ================================= BBCode Parser API ==================================
*/
/**
* Registers a new bbcode in database.
* In 'callback' mode $replacement is normal PHP function body (without declaration) which
* takes $input array of matches as parameter and must return a replacement string. These
* variables are also imported as globals in callback function: $cfg, $sys, $usr, $L, $skin, $sed_groups
*
* @global $db_bbcode;
* @param string $name BBcode name
* @param string $mode Parsing mode, on of the following: 'str' (str_replace), 'pcre' (preg_replace) and 'callback' (preg_replace_callback)
* @param string $pattern Bbcode string or entire regular expression
* @param string $replacement Replacement string or regular substitution or callback body
* @param bool $container Whether bbcode is container (like [bbcode]Something here[/bbcode])
* @param int $priority BBcode priority from 0 to 255. Smaller priority bbcodes are parsed first, 128 is default medium priority.
* @param string $plug Plugin/part name this bbcode belongs to.
* @param bool $postrender Whether this bbcode must be applied on a pre-rendered HTML cache.
* @return bool
*/
function sed_bbcode_add($name, $mode, $pattern, $replacement, $container = true, $priority = 128, $plug = '', $postrender = false)
{
global $db_bbcode;
$bbc['name'] = $name;
$bbc['mode'] = $mode;
$bbc['pattern'] = $pattern;
$bbc['replacement'] = $replacement;
$bbc['container'] = empty($container) ? 0 : 1;
if($priority >= 0 && $priority < 256)
{
$bbc['priority'] = (int) $priority;
}
if(!empty($plug))
{
$bbc['plug'] = $plug;
}
$bbc['postrender'] = empty($postrender) ? 0 : 1;
return sed_sql_insert($db_bbcode, $bbc, 'bbc_') == 1;
}
/**
* Removes a bbcode from parser database.
*
* @global $db_bbcode
* @param int $id BBCode ID or 0 to remove all (use carefully)
* @param string $plug Remove all bbcodes that belong to this plug
* @return bool
*/
function sed_bbcode_remove($id = 0, $plug = '')
{
global $db_bbcode;
if($id > 0)
{
return sed_sql_delete($db_bbcode, "bbc_id = $id") == 1;
}
elseif(!empty($plug))
{
return sed_sql_delete($db_bbcode, "bbc_plug = '" . sed_sql_prep($plug) . "'");
}
else
{
return sed_sql_delete($db_bbcode) > 0;
}
}
/**
* Updates bbcode data in parser database.
*
* @global $db_bbcode;
* @param int $id BBCode ID
* @param bool $enabled Enable the bbcode
* @param string $name BBcode name
* @param string $mode Parsing mode, on of the following: 'str' (str_replace), 'pcre' (preg_replace) and 'callback' (preg_replace_callback)
* @param string $pattern Bbcode string or entire regular expression
* @param string $replacement Replacement string or regular substitution or callback body
* @param bool $container Whether bbcode is container (like [bbcode]Something here[/bbcode])
* @param int $priority BBcode preority from 0 to 255. Smaller priority bbcodes are parsed first, 128 is default medium priority.
* @param bool $postrender Whether this bbcode must be applied on a pre-rendered HTML cache.
* @return bool
*/
function sed_bbcode_update($id, $enabled, $name, $mode, $pattern, $replacement, $container, $priority = 128, $postrender = false)
{
global $db_bbcode;
$bbc['enabled'] = empty($enabled) ? 0 : 1;
if(!empty($name))
{
$bbc['name'] = $name;
}
if(!empty($mode))
{
$bbc['mode'] = $mode;
}
if(!empty($pattern))
{
$bbc['pattern'] = $pattern;
}
if(!empty($replacement))
{
$bbc['replacement'] = $replacement;
}
if($priority >= 0 && $priority < 256)
{
$bbc['priority'] = $priority;
}
$bbc['container'] = empty($container) ? 0 : 1;
$bbc['postrender'] = empty($postrender) ? 0 : 1;
return sed_sql_update($db_bbcode, "bbc_id = $id", $bbc, 'bbc_') == 1;
}
/**
* Loads bbcodes from database if they havent been already loaded.
*
* @global $sed_bbcodes
* @global $db_bbcode
*/
function sed_bbcode_load()
{
global $db_bbcode, $sed_bbcodes, $sed_bbcodes_post, $sed_bbcode_containers;
if(!is_array($sed_bbcodes))
{
$sed_bbcodes = array();
$sed_bbcodes_post = array();
$sed_bbcode_containers = ''; // required for auto-close
$bbc_cntr = array();
$i = 0;
$j = 0;
$res = sed_sql_query("SELECT * FROM $db_bbcode WHERE bbc_enabled = 1 ORDER BY bbc_priority");
while($row = sed_sql_fetchassoc($res))
{
if($row['bbc_postrender'] == 1)
{
foreach($row as $key => $val)
{
$sed_bbcodes_post[$j][str_replace('bbc_', '', $key)] = $val;
}
$j++;
}
else
{
foreach($row as $key => $val)
{
$sed_bbcodes[$i][str_replace('bbc_', '', $key)] = $val;
}
$i++;
}
if($row['bbc_container'] == 1 && !isset($bbc_cntr[$row['bbc_name']]))
{
$sed_bbcode_containers .= $row['bbc_name'] . '|';
$bbc_cntr[$row['bbc_name']] = 1;
}
}
sed_sql_freeresult($res);
if(!empty($sed_bbcode_containers))
{
$sed_bbcode_containers = mb_substr($sed_bbcode_containers, 0, -1);
}
sed_cache_store('sed_bbcodes', $sed_bbcodes, 3550);
sed_cache_store('sed_bbcodes_post', $sed_bbcodes_post, 3550);
sed_cache_store('sed_bbcode_containers', $sed_bbcode_containers, 3550);
}
}
/**
* Clears bbcode cache
*/
function sed_bbcode_clearcache()
{
sed_cache_clear('sed_bbcodes');
sed_cache_clear('sed_bbcodes_post');
sed_cache_clear('sed_bbcode_containers');
}
/**
* Parses bbcodes in text.
*
* @global $sed_bbcodes
* @param string $text Text body
* @param bool $post Post-rendering
* @return string
*/
function sed_bbcode_parse($text, $post = false)
{
global $cfg, $sed_bbcodes, $sed_bbcodes_post, $sed_bbcode_containers;
// BB auto-close
$bbc = array();
if(!$post && preg_match_all('#\[(/)?('.$sed_bbcode_containers.')(=[^\]]*)?\]#i', $text, $mt, PREG_SET_ORDER))
{
$cdata = '';
// Count all unclosed bbcode entries
for($i = 0, $cnt = count($mt); $i < $cnt; $i++)
{
$bb = mb_strtolower($mt[$i][2]);
if($mt[$i][1] == '/')
{
if(empty($cdata))
{
// Protect from "[/foo] [/bar][foo][bar]" trick
if($bbc[$bb] > 0) $bbc[$bb]--;
// else echo 'ERROR: invalid closing bbcode detected';
}
elseif($bb == $cdata)
{
$bbc[$bb]--;
$cdata = '';
}
}
elseif(empty($cdata))
{
// Count opening tag in
$bbc[$bb]++;
if($bb == 'code' || $bb == 'highlight')
{
// Ignore bbcodes in constant data
$cdata = $bb;
}
}
}
// Close all unclosed tags. Produces non XHTML-compliant output
// (doesn't take tag order and semantics into account) but fixes the layout
if(count($bbc) > 0)
{
foreach($bbc as $bb => $c)
{
$text .= str_repeat("[/$bb]", $c);
}
}
}
// Done, ready to parse bbcodes
$cnt = $post ? count($sed_bbcodes_post) : count($sed_bbcodes);
for($i = 0; $i < $cnt; $i++)
{
$bbcode = ($post) ? $sed_bbcodes_post[$i] : $sed_bbcodes[$i];
switch($bbcode['mode'])
{
case 'str':
$text = str_ireplace($bbcode['pattern'], $bbcode['replacement'], $text);
break;
case 'pcre':
$text = preg_replace('`'.$bbcode['pattern'].'`mis', $bbcode['replacement'], $text);
break;
case 'callback':
$code = 'global $cfg, $sys, $usr, $L, $skin, $sed_groups;' . $bbcode['replacement'];
$text = preg_replace_callback('`'.$bbcode['pattern'].'`mis', create_function('$input', $code), $text);
break;
}
}
return $text;
}
/**
* Neutralizes bbcodes in text
*
* @param string $text Source text
* @return string
*/
function sed_bbcode_cdata($text)
{
$res = $text;
//$res = preg_replace('`&(?!amp;)`i', '&$1', $res);
$res = str_replace('[', '[', $res);
$res = str_replace(']', ']', $res);
return $res;
}
/**
* Takes an UTF-8 string and returns an array of ints representing the
* Unicode characters. Astral planes are supported ie. the ints in the
* output can be > 0xFFFF. Occurrances of the BOM are ignored. Surrogates
* are not allowed.
*
* Returns false if the input string isn't a valid UTF-8 octet sequence.
*
* @author Henri Sivonen
* @license Mozilla Public License (MPL)
* @copyright (c) 2003 Henri Sivonen
* @param string $str Unicode string
* @return array
*/
function utf8ToUnicode(&$str)
{
$mState = 0; // cached expected number of octets after the current octet
// until the beginning of the next UTF8 character sequence
$mUcs4 = 0; // cached Unicode character
$mBytes = 1; // cached expected number of octets in the current sequence
$out = array();
$len = strlen($str);
for($i = 0; $i < $len; $i++) {
$in = ord($str{$i});
if (0 == $mState) {
// When mState is zero we expect either a US-ASCII character or a
// multi-octet sequence.
if (0 == (0x80 & ($in))) {
// US-ASCII, pass straight through.
$out[] = $in;
$mBytes = 1;
} else if (0xC0 == (0xE0 & ($in))) {
// First octet of 2 octet sequence
$mUcs4 = ($in);
$mUcs4 = ($mUcs4 & 0x1F) << 6;
$mState = 1;
$mBytes = 2;
} else if (0xE0 == (0xF0 & ($in))) {
// First octet of 3 octet sequence
$mUcs4 = ($in);
$mUcs4 = ($mUcs4 & 0x0F) << 12;
$mState = 2;
$mBytes = 3;
} else if (0xF0 == (0xF8 & ($in))) {
// First octet of 4 octet sequence
$mUcs4 = ($in);
$mUcs4 = ($mUcs4 & 0x07) << 18;
$mState = 3;
$mBytes = 4;
} else if (0xF8 == (0xFC & ($in))) {
/* First octet of 5 octet sequence.
*
* This is illegal because the encoded codepoint must be either
* (a) not the shortest form or
* (b) outside the Unicode range of 0-0x10FFFF.
* Rather than trying to resynchronize, we will carry on until the end
* of the sequence and let the later error handling code catch it.
*/
$mUcs4 = ($in);
$mUcs4 = ($mUcs4 & 0x03) << 24;
$mState = 4;
$mBytes = 5;
} else if (0xFC == (0xFE & ($in))) {
// First octet of 6 octet sequence, see comments for 5 octet sequence.
$mUcs4 = ($in);
$mUcs4 = ($mUcs4 & 1) << 30;
$mState = 5;
$mBytes = 6;
} else {
/* Current octet is neither in the US-ASCII range nor a legal first
* octet of a multi-octet sequence.
*/
return false;
}
} else {
// When mState is non-zero, we expect a continuation of the multi-octet
// sequence
if (0x80 == (0xC0 & ($in))) {
// Legal continuation.
$shift = ($mState - 1) * 6;
$tmp = $in;
$tmp = ($tmp & 0x0000003F) << $shift;
$mUcs4 |= $tmp;
if (0 == --$mState) {
/* End of the multi-octet sequence. mUcs4 now contains the final
* Unicode codepoint to be output
*
* Check for illegal sequences and codepoints.
*/
// From Unicode 3.1, non-shortest form is illegal
if (((2 == $mBytes) && ($mUcs4 < 0x0080)) ||
((3 == $mBytes) && ($mUcs4 < 0x0800)) ||
((4 == $mBytes) && ($mUcs4 < 0x10000)) ||
(4 < $mBytes) ||
// From Unicode 3.2, surrogate characters are illegal
(($mUcs4 & 0xFFFFF800) == 0xD800) ||
// Codepoints outside the Unicode range are illegal
($mUcs4 > 0x10FFFF)) {
return false;
}
if (0xFEFF != $mUcs4) {
// BOM is legal but we don't want to output it
$out[] = $mUcs4;
}
//initialize UTF8 cache
$mState = 0;
$mUcs4 = 0;
$mBytes = 1;
}
} else {
/* ((0xC0 & (*in) != 0x80) && (mState != 0))
*
* Incomplete multi-octet sequence.
*/
return false;
}
}
}
return $out;
}
/**
* JavaScript HTML obfuscator to protect some parts (like email) from bots
*
* @param string $text Source text
* @return string
*/
function sed_obfuscate($text)
{
$enc_string = '[';
$ut = utf8ToUnicode($text);
$length = count($ut);
for ($i=0; $i < $length; $i++)
{
$enc_string .= $ut[$i].',';
}
$enc_string = substr($enc_string, 0, -1).']';
$name = 'a'.sed_unique(8);
$script = '<script type="text/javascript">var '.$name.' = '.$enc_string.','.$name.'_d = ""; for(var ii = 0; ii < '.$name.'.length; ii++) { var c = '.$name.'[ii]; '.$name.'_d += String.fromCharCode(c); } document.write('.$name.'_d)</script>';
return $script;
}
/**
* Supplimentary email obfuscator callback
*
* @param array $m PCRE entry
* @return string
*/
function sed_obfuscate_eml($m)
{
return $m[1].sed_obfuscate('<a href="mailto:'.$m[2].'">'.$m[2].'</a>');
}
/**
* Automatically detect and parse URLs in text into HTML
*
* @param string $text Text body
* @return string
*/
function sed_parse_autourls($text)
{
$text = preg_replace('`(^|\s)(http|https|ftp)://([^\s"\'\[]+)`', '$1<a href="$2://$3">$2://$3</a>', $text);
$text = preg_replace_callback('`(^|\s)([\w\p{L}][\.\w\p{L}\-]*@[\w\p{L}\.\-]+\.[\w\p{L}]+)`u', 'sed_obfuscate_eml', $text);
return $text;
}
/**
* Supplimentary br stripper callback
*
* @param array $m PCRE entries
* @return string
*/
function sed_parse_pre($m)
{
return str_replace('<br />', '', $m[0]);
}
/**
* Parses text body
*
* @param string $text Source text
* @param bool $parse_bbcodes Enable bbcode parsing
* @param bool $parse_smilies Enable emoticons
* @param bool $parse_newlines Replace line breaks with <br />
* @return string
*/
function sed_parse($text, $parse_bbcodes = TRUE, $parse_smilies = TRUE, $parse_newlines = TRUE)
{
global $cfg, $sys, $sed_smilies, $L, $usr;
if($cfg['parser_custom'] && function_exists('sed_custom_parse'))
{
$text = sed_custom_parse($text, $parse_bbcodes, $parse_smilies, $parse_newlines);
}
if(!$cfg['parser_disable'])
{
$code = array();
$unique_seed = $sys['unique'];
$ii = 10000;
$text = sed_parse_autourls($text);
if($parse_smilies && is_array($sed_smilies))
{
foreach($sed_smilies as $k => $v)
{
$ii++;
$key = '**'.$ii.$unique_seed.'**';
$code[$key]= '<img class="aux smiley" src="./images/smilies/'.$v['file'].'" alt="'.htmlspecialchars($v['code']).'" />';
$text = preg_replace('#(^|\s)'.preg_quote($v['code']).'(\s|$)#', '$1'.$key.'$2', $text);
if(htmlspecialchars($v['code']) != $v['code'])
{
// Fix for cc inserts
$text = preg_replace('#(^|\s)'.preg_quote(htmlspecialchars($v['code'])).'(\s|$)#', '$1'.$key.'$2', $text);
}
}
}
if($parse_bbcodes)
{
$text = sed_bbcode_parse($text);
}
if ($parse_bbcodes || $parse_smilies)
{
foreach($code as $x => $y)
{ $text = str_replace($x, $y, $text); }
}
if ($parse_newlines)
{
$text = nl2br($text);
$text = str_replace("\r", '', $text);
// Strip extraneous breaks
$text = preg_replace('#<(/?)(p|hr|ul|ol|li|blockquote|table|tr|td|th|div|h1|h2|h3|h4|h5)(.*?)>(\s*)<br />#', '<$1$2$3>', $text);
$text = preg_replace_callback('#<pre[^>]*>(.+?)</pre>#sm', 'sed_parse_pre', $text);
}
}
return $text;
}
/**
* Post-render parser function
*
* @param string $text Text body
* @param string $area Site area to check bbcode enablement
* @return string
*/
function sed_post_parse($text, $area = '')
{
global $cfg;
if($cfg['parser_custom'] && function_exists('sed_custom_post_parse'))
{
$text = sed_custom_post_parse($text, $area);
}
if(!$cfg['parser_disable'] && (empty($area) || $cfg["parsebbcode$area"]))
{
$text = sed_bbcode_parse($text, true);
}
return $text;
}
/*
* =========================== Output forming functions ===========================
*/
/* ------------------ */
/**
* Builds a javascript function for text insertion
*
* @param string $c1 Form name
* @param string $c2 Field name
* @return string
*/
function sed_build_addtxt($c1, $c2)
{
$result = "
function addtxt(text) {
insertText(document, '$c1', '$c2', text);
}
";
return($result);
}
/**
* Calculates age out of D.O.B.
*
* @param int $birth Date of birth as UNIX timestamp
* @return int
*/
function sed_build_age($birth)
{
global $sys;
if ($birth==1)
{ return ('?'); }
$day1 = @date('d', $birth);
$month1 = @date('m', $birth);
$year1 = @date('Y', $birth);
$day2 = @date('d', $sys['now_offset']);
$month2 = @date('m', $sys['now_offset']);
$year2 = @date('Y', $sys['now_offset']);
$age = ($year2-$year1)-1;
if ($month1<$month2 || ($month1==$month2 && $day1<=$day2))
{ $age++; }
if($age < 0)
{ $age += 136; }
return ($age);
}
/**
* Builds category path
*
* @param string $cat Category code
* @param string $mask Format mask
* @return string
*/
function sed_build_catpath($cat, $mask)
{
global $sed_cat, $cfg;
$mask = str_replace('%25', '%', $mask);
$mask = str_replace('%24', '$', $mask);
if($cfg['homebreadcrumb'])
{
$tmp[] = '<a href="'.$cfg['mainurl'].'">'.htmlspecialchars($cfg['maintitle']).'</a>';
}
$pathcodes = explode('.', $sed_cat[$cat]['path']);
foreach($pathcodes as $k => $x)
{
if ($x != 'system')
{
$tmp[]= sprintf($mask, sed_url('list', 'c='.$x), $sed_cat[$x]['title']);
}
}
return is_array($tmp) ? implode(' '.$cfg['separator'].' ', $tmp) : '';
}
/* ------------------ */
// TODO replace with new comments plugin
// TODO I messed up this code, please see if I did huge mistakes and inform me (oc)
function sed_build_comments($code, $url, $display = true)
{
global $db_com, $db_users, $db_pages, $cfg, $usr, $L, $sys;
list($usr['auth_read_com'], $usr['auth_write_com'], $usr['isadmin_com']) = sed_auth('comments', 'a');
sed_block($usr['auth_read_com']);
if ($cfg['disable_comments'] || !$usr['auth_read_com']) return (array('',''));
$sep = (mb_strpos($url, '?') !== false) ? '&' : '?';
$ina = sed_import('ina','G','ALP');
$ind = sed_import('ind','G','INT');
$d = sed_import('d', 'G', 'INT');
$d = empty($d) ? 0 : (int) $d;
if ($ina == 'send' && $usr['auth_write_com'] && $display)
{
sed_shield_protect();
$rtext = sed_import('rtext','P','HTM');
/* == Hook for the plugins == */
$extp = sed_getextplugins('comments.send.first');
if (is_array($extp)) { foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$error_string .= (mb_strlen($rtext) < $cfg['commentminsize']) ? $L['com_commenttooshort']."<br />" : '';
$error_string .= ($cfg['commentsize'] && mb_strlen($rtext) > $cfg['commentsize']) ? $L['com_commenttoolong']
.'<br />' : '';
if (empty($error_string))
{
$rhtml = $cfg['parser_cache'] ?
sed_parse(htmlspecialchars($rtext), $cfg['parsebbcodecom'], $cfg['parsesmiliescom'], true) : '';
$sql = sed_sql_query("INSERT INTO $db_com (com_code, com_author, com_authorid, com_authorip, com_text,
com_html, com_date) VALUES ('".sed_sql_prep($code)."', '".sed_sql_prep($usr['name'])."', "
.(int)$usr['id'].", '".$usr['ip']."', '".sed_sql_prep($rtext)."', '".sed_sql_prep($rhtml)."', "
.(int)$sys['now_offset'].")");
$id = sed_sql_insertid();
if (mb_substr($code, 0, 1) =='p')
{
$page_id = mb_substr($code, 1, 10);
$sql = sed_sql_query("UPDATE $db_pages SET page_comcount='".sed_get_comcount($code)."'
WHERE page_id='".$page_id."'");
}
/* == Hook for the plugins == */
$extp = sed_getextplugins('comments.send.new');
if (is_array($extp)) { foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
sed_shield_update(20, 'New comment');
header('Location: ' . SED_ABSOLUTE_URL . str_replace('&', '&', $url) . '#c' . $id);
exit;
}
}
if ($ina == 'delete' && $usr['isadmin_com'])
{
sed_check_xg();
$sql = sed_sql_query("SELECT * FROM $db_com WHERE com_id='$ind' LIMIT 1");
if ($row = sed_sql_fetchassoc($sql))
{
if ($cfg['trash_comment']) { sed_trash_put('comment', $L['Comment']." #".$ind." (".$row['com_author'].")", $ind, $row); }
$sql = sed_sql_query("DELETE FROM $db_com WHERE com_id='$ind'");
if (mb_substr($row['com_code'], 0, 1) == 'p')
{
$page_id = mb_substr($row['com_code'], 1, 10);
$sql = sed_sql_query("UPDATE $db_pages SET page_comcount=".sed_get_comcount($row['com_code'])." WHERE page_id=".$page_id);
}
sed_log('Deleted comment #'.$ind.' in "'.$code.'"', 'adm');
}
header('Location: ' . SED_ABSOLUTE_URL . str_replace('&', '&', $url) . '#comments');
exit;
}
$error_string .= ($ina == 'added') ? $L['com_commentadded'].'<br />' : '';
$t = new XTemplate(sed_skinfile('comments'));
/* == Hook for the plugins == */
$extp = sed_getextplugins('comments.main');
if (is_array($extp)) { foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$sql = sed_sql_query("SELECT c.*, u.user_avatar FROM $db_com AS c
LEFT JOIN $db_users AS u ON u.user_id=c.com_authorid
WHERE com_code='$code' ORDER BY com_id ASC LIMIT $d, ".$cfg['maxcommentsperpage']);
if (!empty($error_string))
{
$t->assign('COMMENTS_ERROR_BODY', $error_string);
$t->parse('COMMENTS.COMMENTS_ERROR');
}
if ($usr['auth_write_com'] && $display)
{
$pfs = ($usr['id']>0) ? sed_build_pfs($usr['id'], 'newcomment', 'rtext', $L['Mypfs']) : '';
$pfs .= (sed_auth('pfs', 'a', 'A')) ? ' '.sed_build_pfs(0, 'newcomment', 'rtext', $L['SFS']) : '';
$post_main = '<textarea class="minieditor" name="rtext" rows="10" cols="120">'.$rtext.'</textarea>'.$pfs;
}
$t->assign(array(
'COMMENTS_CODE' => $code,
'COMMENTS_FORM_SEND' => $url . $sep . 'ina=send',
'COMMENTS_FORM_AUTHOR' => $usr['name'],
"COMMENTS_FORM_AUTHORID" => $usr['id'],
'COMMENTS_FORM_TEXT' => $post_main,
'COMMENTS_FORM_TEXTBOXER' => $post_main,
'COMMENTS_FORM_MYPFS' => $pfs,
'COMMENTS_DISPLAY' => $cfg['expand_comments'] ? '' : 'none'
));
if ($usr['auth_write_com'] && $display)
{
/* == Hook for the plugins == */
$extp = sed_getextplugins('comments.newcomment.tags');
if (is_array($extp)) { foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$t->parse('COMMENTS.COMMENTS_NEWCOMMENT');
}
elseif (!$display)
{
$t->assign('COMMENTS_CLOSED', $L['com_closed']);
$t->parse('COMMENTS.COMMENTS_CLOSED');
}
if (sed_sql_numrows($sql)>0)
{
$i = $d;
/* === Hook - Part1 : Set === */
$extp = sed_getextplugins('comments.loop');
/* ===== */
while ($row = sed_sql_fetcharray($sql))
{
$i++;
$com_author = htmlspecialchars($row['com_author']);
$com_admin = ($usr['isadmin_com']) ? $L['Ip'] . ':' . sed_build_ipsearch($row['com_authorip'])
. ' ' . $L['Delete'] . ':[<a href="' . $url . $sep . 'ina=delete&ind=' . $row['com_id']
. '&' .sed_xg().'">x</a>]' : '' ;
$com_authorlink = sed_build_user($row['com_authorid'], $com_author);
if($cfg['parser_cache'])
{
if(empty($row['com_html']) && !empty($row['com_text']))
{
$row['com_html'] = sed_parse(htmlspecialchars($row['com_text']), $cfg['parsebbcodecom'],
$cfg['parsesmiliescom'], true);
sed_sql_query("UPDATE $db_com SET com_html = '".sed_sql_prep($row['com_html'])."'
WHERE com_id = " . $row['com_id']);
}
$com_text = $cfg['parsebbcodepages'] ? sed_post_parse($row['com_html'])
: htmlspecialchars($row['com_text']);
}
else
{
$com_text = sed_parse(htmlspecialchars($row['com_text']), $cfg['parsebbcodecom'],
$cfg['parsesmiliescom'], true);
$com_text = sed_post_parse($com_text, 'pages');
}
$t-> assign(array(
'COMMENTS_ROW_ID' => $row['com_id'],
'COMMENTS_ROW_ORDER' => $i,
'COMMENTS_ROW_URL' => $url . '#c' . $row['com_id'],
'COMMENTS_ROW_AUTHOR' => $com_authorlink,
'COMMENTS_ROW_AUTHORID' => $row['com_authorid'],
'COMMENTS_ROW_AVATAR' => sed_build_userimage($row['user_avatar'], 'avatar'),
'COMMENTS_ROW_TEXT' => $com_text,
'COMMENTS_ROW_DATE' => @date($cfg['dateformat'], $row['com_date'] + $usr['timezone'] * 3600),
'COMMENTS_ROW_ADMIN' => $com_admin,
));
/* === Hook - Part2 : Include === */
if (is_array($extp)) { foreach($extp as $k => $pl) { include($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$t->parse('COMMENTS.COMMENTS_ROW');
}
$totalitems = sed_sql_result(sed_sql_query("SELECT COUNT(*) FROM $db_com WHERE com_code='$code'"), 0, 0);
$pagnav = sed_pagination($url, $d, $totalitems, $cfg['maxcommentsperpage']);
list($pagination_prev, $pagination_next) = sed_pagination_pn($url, $d, $totalitems, $cfg['maxcommentsperpage'], TRUE);
if (!$cfg['expand_comments'])
{
// A dirty fix for pagination anchors
$pagnav = preg_replace('/href="(.+?)"/', 'href="$1#comments"', $pagnav);
$pagination_prev = preg_replace('/href="(.+?)"/', 'href="$1#comments"', $pagination_prev);
$pagination_next = preg_replace('/href="(.+?)"/', 'href="$1#comments"', $pagination_next);
}
$t->assign(array(
'COMMENTS_PAGES_INFO' => $L['Total'] . ' : ' . $totalitems . ', ' . $L['comm_on_page'] . ': ' . ($i - $d),
'COMMENTS_PAGES_PAGESPREV' => $pagination_prev,
'COMMENTS_PAGES_PAGNAV' => $pagnav,
'COMMENTS_PAGES_PAGESNEXT' => $pagination_next
));
$t->parse('COMMENTS.PAGNAVIGATOR');
}
elseif (!sed_sql_numrows($sql) && $display)
{
$t-> assign(array(
'COMMENTS_EMPTYTEXT' => $L['com_nocommentsyet'],
));
$t->parse('COMMENTS.COMMENTS_EMPTY');
}
/* == Hook for the plugins == */
$extp = sed_getextplugins('comments.tags');
if (is_array($extp)) { foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$t->parse('COMMENTS');
$res_display = $t->text('COMMENTS');
$res = '<a href="' . $url . '#comments" class="comments_link"><img src="skins/' . $usr['skin']
. '/img/system/icon-comment.gif" alt="" />';
if ($cfg['countcomments'])
{
if (isset($totalitems)) $nbcomment = $totalitems;
else $nbcomment = sed_sql_result(sed_sql_query("SELECT COUNT(*) FROM $db_com where com_code='$code'"), 0, 0);
$res .= ' (' . $nbcomment . ')';
}
$res .= '</a>';
return(array($res, $res_display, $nbcomment));
}
/**
* Returns country text button
*
* @param string $flag Country code
* @return string
*/
function sed_build_country($flag)
{
global $sed_countries;
$flag = (empty($flag)) ? '00' : $flag;
return '<a href="'.sed_url('users', 'f=country_'.$flag).'">'.$sed_countries[$flag].'</a>';
}
/**
* Returns user email link
*
* @param string $email E-mail address
* @param bool $hide Hide email option
* @return string
*/
function sed_build_email($email, $hide = false)
{
global $L;
if($hide)
{
return $L['Hidden'];
}
elseif(!empty($email) && preg_match('#^[\w\p{L}][\.\w\p{L}\-]*@[\w\p{L}\.\-]+\.[\w\p{L}]+$#u', $email))
{
return sed_obfuscate('<a href="mailto:'.$email.'">'.$email.'</a>');
}
}
/**
* Returns Extra fields edit fields
*
* @param string $rowname Post/SQL/Lang row
* @param string $tpl_tag Template tag area
* @param array $extrafields Extra fields data
* @param array $data Existing data for fields
* @param bool $importnew Import type new
* @return array
*/
function sed_build_extrafields($rowname, $tpl_tag, $extrafields, $data=array(), $importnew=FALSE)
{
global $L, $t, $global;
$importrowname = ($importnew) ? 'new'.$rowname : 'r'.$rowname;
foreach($extrafields as $i=>$row)
{
isset($L[$rowname.'_'.$row['field_name'].'_title']) ? $t->assign($tpl_tag.'_'.strtoupper($row['field_name']).'_TITLE', $L[$rowname.'_'.$row['field_name'].'_title']) : $t->assign($tpl_tag.'_'.strtoupper($row['field_name']).'_TITLE', $row['field_description']);
$t1 = $tpl_tag.'_'.strtoupper($row['field_name']);
$t2 = $row['field_html'];
switch($row['field_type'])
{
case "input":
$t2 = str_replace('<input ','<input name="'.$importrowname.$row['field_name'].'" ', $t2);
$t2 = str_replace('<input ','<input value="'.htmlspecialchars($data[$rowname.'_'.$row['field_name']]).'" ', $t2);
break;
case "textarea":
$t2 = str_replace('<textarea ','<textarea name="'.$importrowname.$row['field_name'].'" ', $t2);
$t2 = str_replace('</textarea>',htmlspecialchars($data[$rowname.'_'.$row['field_name']]).'</textarea>', $t2);
break;
case "select":
$t2 = str_replace('<select','<select name="'.$importrowname.$row['field_name'].'"', $t2);
$options = "";
$opt_array = explode(",",$row['field_variants']);
if(count($opt_array)!=0)
foreach ($opt_array as $var)
{
$var_text = (!empty($L[$rowname.'_'.$row['field_name'].'_'.$var])) ? $L[$rowname.'_'.$row['field_name'].'_'.$var] : $var;
$sel = ($var == $data[$rowname.'_'.$row['field_name']]) ? ' selected="selected"' : '';
$options .= "<option value=\"$var\" $sel>$var_text</option>";
}
$t2 = str_replace("</select>","$options</select>",$t2);
break;
case "checkbox":
$t2 = str_replace('<input','<input name="'.$importrowname.$row['field_name'].'"', $t2);
$sel = ($data[$rowname.'_'.$row['field_name']] == 1) ? ' checked' : '';
$t2 = str_replace('<input ','<input value="on" '.$sel.' ', $t2);
break;
case "radio":
$t2 = str_replace('<input','<input name="'.$importrowname.$row['field_name'].'"', $t2);
$buttons = "";
$opt_array = explode(",",$row['field_variants']);
if(count($opt_array)!=0)
foreach ($opt_array as $var)
{
$var_text = (!empty($L[$rowname.'_'.$row['field_name'].'_'.$var])) ? $L[$rowname.'_'.$row['field_name'].'_'.$var] : $var;
$sel = ($var == $data[$rowname.'_'.$row['field_name']]) ? ' checked="checked"' : '';
$buttons .= str_replace('/>', 'value="'.$var.'"'.$sel.' />'.$var_text.' ', $t2);
}
$t2 = $buttons;
break;
}
$return_arr[$t1] = $t2;
}
return $return_arr;
}
/**
* Returns Extra fields date
*
* @param string $rowname Lang row
* @param string $type Extra field type
* @param string $field_name Extra field name
* @param string $value Existing user value
* @return string
*/
function sed_build_extrafields_data($rowname, $type, $field_name, $value)
{
global $L;
$value = htmlspecialchars($value);
switch($type)
{
case "input":
return $value;
break;
case "textarea":
return $value;
break;
case "select":
return (!empty($L[$rowname.'_'.$field_name.'_'.$value])) ? $L[$rowname.'_'.$field_name.'_'.$value] : $value;
break;
case "checkbox":
return $value;
break;
case "radio":
return (!empty($L[$rowname.'_'.$field_name.'_'.$value])) ? $L[$rowname.'_'.$field_name.'_'.$value] : $value;
break;
}
}
/**
* Returns country flag button
*
* @param string $flag Country code
* @return string
*/
function sed_build_flag($flag)
{
global $sed_countries;
$flag = (empty($flag)) ? '00' : $flag;
return '<a href="'.sed_url('users', 'f=country_'.$flag).'" title="'.$sed_countries[$flag].'"><img src="images/flags/f-'.$flag.'.gif" alt="'.$flag.'" /></a>';
}
/**
* Returns forum thread path
*
* @param int $sectionid Section ID
* @param string $title Thread title
* @param string $category Category code
* @param string $link Display as links
* @param mixed $master Master section
* @return string
*/
function sed_build_forums($sectionid, $title, $category, $link = TRUE, $master = false)
{
global $sed_forums_str, $cfg, $db_forum_sections, $L;
$pathcodes = explode('.', $sed_forums_str[$category]['path']);
if($link)
{
if($cfg['homebreadcrumb'])
{
$tmp[] = '<a href="'.$cfg['mainurl'].'">'.htmlspecialchars($cfg['maintitle']).'</a>';
}
$tmp[] = '<a href="'.sed_url('forums').'">'.$L['Forums'].'</a>';
foreach($pathcodes as $k => $x)
{
$tmp[] = '<a href="'.sed_url('forums', 'c='.$x, '#'.$x).'">'.htmlspecialchars($sed_forums_str[$x]['title']).'</a>';
}
if(is_array($master))
{
$tmp[] = '<a href="'.sed_url('forums', 'm=topics&s='.$master[0]).'">'.htmlspecialchars($master[1]).'</a>';
}
$tmp[] = '<a href="'.sed_url('forums', 'm=topics&s='.$sectionid).'">'.htmlspecialchars($title).'</a>';
}
else
{
foreach($pathcodes as $k => $x)
{
$tmp[]= htmlspecialchars($sed_forums_str[$x]['title']);
}
if(is_array($master))
{
$tmp[] = $master[1];
}
$tmp[] = htmlspecialchars($title);
}
return implode(' '.$cfg['separator'].' ', $tmp);
}
/* ------------------ */
/**
* Returns group link (button)
*
* @param int $grpid Group ID
* @return string
*/
function sed_build_group($grpid)
{
if(empty($grpid)) return '';
global $sed_groups, $L;
if($sed_groups[$grpid]['hidden'])
{
if(sed_auth('users', 'a', 'A'))
{
return '<a href="'.sed_url('users', 'gm='.$grpid).'">'.$sed_groups[$grpid]['title'].'</a> ('.$L['Hidden'].')';
}
else
{
return $L['Hidden'];
}
}
else
{
return '<a href="'.sed_url('users', 'gm='.$grpid).'">'.$sed_groups[$grpid]['title'].'</a>';
}
}
/**
* Builds "edit group" option group for "user edit" part
*
* @param int $userid Edited user ID
* @param bool $edit Permission
* @param int $maingrp User main group
* @return string
*/
function sed_build_groupsms($userid, $edit=FALSE, $maingrp=0)
{
global $db_groups_users, $sed_groups, $L, $usr;
$sql = sed_sql_query("SELECT gru_groupid FROM $db_groups_users WHERE gru_userid='$userid'");
while ($row = sed_sql_fetcharray($sql))
{
$member[$row['gru_groupid']] = TRUE;
}
foreach($sed_groups as $k => $i)
{
$checked = ($member[$k]) ? "checked=\"checked\"" : '';
$checked_maingrp = ($maingrp==$k) ? "checked=\"checked\"" : '';
$readonly = (!$edit || $usr['level'] < $sed_groups[$k]['level'] || $k==SED_GROUP_GUESTS || $k==SED_GROUP_INACTIVE || $k==SED_GROUP_BANNED || ($k==SED_GROUP_TOPADMINS && $userid==1)) ? "disabled=\"disabled\"" : '';
$readonly_maingrp = (!$edit || $usr['level'] < $sed_groups[$k]['level'] || $k==SED_GROUP_GUESTS || ($k==SED_GROUP_INACTIVE && $userid==1) || ($k==SED_GROUP_BANNED && $userid==1)) ? "disabled=\"disabled\"" : '';
if ($member[$k] || $edit)
{
if (!($sed_groups[$k]['hidden'] && !sed_auth('users', 'a', 'A')))
{
$res .= "<input type=\"radio\" class=\"radio\" name=\"rusermaingrp\" value=\"$k\" ".$checked_maingrp." ".$readonly_maingrp." /> \n";
$res .= "<input type=\"checkbox\" class=\"checkbox\" name=\"rusergroupsms[$k]\" ".$checked." $readonly />\n";
$res .= ($k == SED_GROUP_GUESTS) ? $sed_groups[$k]['title'] : "<a href=\"".sed_url('users', 'gm='.$k)."\">".$sed_groups[$k]['title']."</a>";
$res .= ($sed_groups[$k]['hidden']) ? ' ('.$L['Hidden'].')' : '';
$res .= "<br />";
}
}
}
return $res;
}
/**
* Returns user ICQ pager link
*
* @param int $text ICQ number
* @return string
*/
function sed_build_icq($text)
{
global $cfg;
$text = (int) $text;
if($text > 0)
{
return $text.' <a href="http://www.icq.com/'.$text.'#pager"><img src="http://web.icq.com/whitepages/online?icq='.$text.'&img=5" alt="" /></a>';
}
return '';
}
/**
* Returns IP Search link
*
* @param string $ip IP mask
* @return string
*/
function sed_build_ipsearch($ip)
{
global $sys;
if(!empty($ip))
{
return '<a href="'.sed_url('admin', 'm=tools&p=ipsearch&a=search&id='.$ip.'&x='.$sys['xk']).'">'.$ip.'</a>';
}
return '';
}
/**
* Returns MSN link as e-mail link
*
* @param string $msn MSN address
* @return string
*/
function sed_build_msn($msn)
{
return sed_build_email($msn);
}
/**
* Odd/even class choser for row
*
* @param int $number Row number
* @return string
*/
function sed_build_oddeven($number)
{
return ($number % 2 == 0 ) ? 'even' : 'odd';
}
/* ------------------ */
// TODO eliminate this function
function sed_build_pfs($id, $c1, $c2, $title)
{
global $L, $cfg, $usr, $sed_groups;
if ($cfg['disable_pfs'])
{ $res = ''; }
else
{
if ($id==0)
{ $res = "<a href=\"javascript:pfs('0','".$c1."','".$c2."')\">".$title."</a>"; }
elseif ($sed_groups[$usr['maingrp']]['pfs_maxtotal']>0 && $sed_groups[$usr['maingrp']]['pfs_maxfile']>0 && sed_auth('pfs', 'a', 'R'))
{ $res = "<a href=\"javascript:pfs('".$id."','".$c1."','".$c2."')\">".$title."</a>"; }
else
{ $res = ''; }
}
return($res);
}
/**
* Returns user PM link
*
* @param int $user User ID
* @return string
*/
function sed_build_pm($user)
{
global $usr, $L;
return '<a href="'.sed_url('pm', 'm=send&to='.$user).'" title="'.$L['pm_sendnew'].'"><img src="skins/'.$usr['skin'].'/img/system/icon-pm.gif" alt="'.$L['pm_sendnew'].'" /></a>';
}
/* ------------------ */
/**
* Builds ratings for an item
*
* @param $code Item code
* @param $url Base url
* @param $display Display available for edit
* @return array
*/
function sed_build_ratings($code, $url, $display)
{
global $db_ratings, $db_rated, $db_users, $cfg, $usr, $sys, $L;
static $called = false;
list($usr['auth_read_rat'], $usr['auth_write_rat'], $usr['isadmin_rat']) = sed_auth('ratings', 'a');
if ($cfg['disable_ratings'] || !$usr['auth_read_rat'])
{
return (array('',''));
}
$ajax = sed_import('ajax', 'G', 'BOL');
if ($ajax)
{
$rcode = sed_import('rcode', 'G', 'ALP');
if (!empty($rcode)) $code = $rcode;
}
$sql = sed_sql_query("SELECT * FROM $db_ratings WHERE rating_code='$code' LIMIT 1");
if($row = sed_sql_fetcharray($sql))
{
$rating_average = $row['rating_average'];
$yetrated = TRUE;
if($rating_average<1)
{ $rating_average = 1; }
elseif ($rating_average>10)
{ $rating_average = 10; }
$rating_cntround = round($rating_average, 0);
}
else
{
$yetrated = FALSE;
$rating_average = 0;
$rating_cntround = 0;
}
if($ajax)
{
ob_clean();
echo $rating_cntround;
ob_flush();
exit;
}
$rating_fancy = '';
for($i = 1; $i <= 10; $i++)
{
$star_class = ($i <= $rating_cntround) ? 'star-rating star-rating-on' : 'star-rating star-rating-readonly';
$star_margin = (in_array(($i/2), array(1,2,3,4,5))) ? '-8' : '0';
$rating_fancy .= '<div style="width: 8px;" class="'.$star_class.'"><a style="margin-left: '.$star_margin.'px;" title="'.$L['rat_choice' . $i].'">'.$i.'</a></div>';
}
if(!$display)
{
return array($rating_fancy, '');
}
$sep = (mb_strpos($url, '?') !== false) ? '&' : '?';
$inr = sed_import('inr','G','ALP');
$newrate = sed_import('rate_' . $code,'P','INT');
$newrate = (!empty($newrate)) ? $newrate : 0;
if(!$cfg['ratings_allowchange'])
{
$alr_rated = sed_sql_result(sed_sql_query("SELECT COUNT(*) FROM ".$db_rated." WHERE rated_userid=".$usr['id']." AND rated_code = '".sed_sql_prep($code)."'"), 0, 'COUNT(*)');
}
else
{
$alr_rated = 0;
}
if ($inr == 'send' && $newrate >= 0 && $newrate <= 10 && $usr['auth_write_rat'] && $alr_rated <= 0)
{
/* == Hook for the plugins == */
$extp = sed_getextplugins('ratings.send.first');
if (is_array($extp))
{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$sql = sed_sql_query("DELETE FROM $db_rated WHERE rated_code='".sed_sql_prep($code)."' AND rated_userid='".$usr['id']."' ");
if (!$yetrated)
{
$sql = sed_sql_query("INSERT INTO $db_ratings (rating_code, rating_state, rating_average, rating_creationdate, rating_text) VALUES ('".sed_sql_prep($code)."', 0, ".(int)$newrate.", ".(int)$sys['now_offset'].", '') ");
}
$sql = ($newrate) ? sed_sql_query("INSERT INTO $db_rated (rated_code, rated_userid, rated_value) VALUES ('".sed_sql_prep($code)."', ".(int)$usr['id'].", ".(int)$newrate.")") : '';
$sql = sed_sql_query("SELECT COUNT(*) FROM $db_rated WHERE rated_code='$code'");
$rating_voters = sed_sql_result($sql, 0, "COUNT(*)");
if ($rating_voters>0)
{
$ratingnewaverage = sed_sql_result(sed_sql_query("SELECT AVG(rated_value) FROM $db_rated WHERE rated_code='$code'"), 0, "AVG(rated_value)");
$sql = sed_sql_query("UPDATE $db_ratings SET rating_average='$ratingnewaverage' WHERE rating_code='$code'");
}
else
{
$sql = sed_sql_query("DELETE FROM $db_ratings WHERE rating_code='$code' ");
}
/* == Hook for the plugins == */
$extp = sed_getextplugins('ratings.send.done');
if (is_array($extp))
{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
header('Location: ' . SED_ABSOLUTE_URL . $url);
exit;
}
if ($usr['id'] > 0)
{
$sql1 = sed_sql_query("SELECT rated_value FROM $db_rated WHERE rated_code='$code' AND rated_userid='".$usr['id']."' LIMIT 1");
if ($row1 = sed_sql_fetcharray($sql1))
{
$alreadyvoted = ($cfg['ratings_allowchange']) ? FALSE : TRUE;
$rating_uservote = $L['rat_alreadyvoted']." (".$row1['rated_value'].")";
}
}
$t = new XTemplate(sed_skinfile('ratings'));
if (!$called && $usr['id'] > 0 && !$alreadyvoted)
{
// Link JS and CSS
$sep = (mb_strpos($url, '?') !== false) ? '&' : '?';
$t->assign('RATINGS_AJAX_REQUEST', $url . $sep .'ajax=1');
$t->parse('RATINGS.RATINGS_INCLUDES');
$called = true;
}
/* == Hook for the plugins == */
$extp = sed_getextplugins('ratings.main');
if (is_array($extp))
{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$sep = (mb_strpos($url, '?') !== false) ? '&' : '?';
if ($yetrated)
{
$sql = sed_sql_query("SELECT COUNT(*) FROM $db_rated WHERE rated_code='$code' ");
$rating_voters = sed_sql_result($sql, 0, "COUNT(*)");
$rating_average = $row['rating_average'];
$rating_since = $L['rat_since']." ".date($cfg['dateformat'], $row['rating_creationdate'] + $usr['timezone'] * 3600);
if ($rating_average<1)
{ $rating_average = 1; }
elseif ($ratingaverage>10)
{ $rating_average = 10; }
$rating = round($rating_average,0);
$rating_averageimg = "<img src=\"skins/".$usr['skin']."/img/system/vote".$rating.".gif\" alt=\"\" />";
$sql = sed_sql_query("SELECT COUNT(*) FROM $db_rated WHERE rated_code='$code' ");
$rating_voters = sed_sql_result($sql, 0, "COUNT(*)");
}
else
{
$rating_voters = 0;
$rating_since = '';
$rating_average = 0;
$rating_averageimg = '';
}
$t->assign(array(
'RATINGS_CODE' => $code,
'RATINGS_AVERAGE' => $rating_average,
'RATINGS_RATING' => $rating,
'RATINGS_AVERAGEIMG' => $rating_averageimg,
'RATINGS_VOTERS' => $rating_voters,
'RATINGS_SINCE' => $rating_since,
'RATINGS_FANCYIMG' => $rating_fancy,
'RATINGS_USERVOTE' => $rating_uservote
));
/* == Hook for the plugins == */
$extp = sed_getextplugins('ratings.tags');
if (is_array($extp))
{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ===== */
$vote_block = ($usr['id']>0 && !$alreadyvoted) ? 'NOTVOTED.' : 'VOTED.';
for($i = 1; $i <= 10; $i++)
{
$checked = $i == $rating_cntround ? 'checked="checked"' : '';
$t->assign(array(
'RATINGS_ROW_VALUE' => $i,
'RATINGS_ROW_TITLE' => $L['rat_choice' . $i],
'RATINGS_ROW_CHECKED' => $checked,
));
$t->parse('RATINGS.'.$vote_block.'RATINGS_ROW');
}
if($vote_block == 'NOTVOTED.')
{
$t->assign("RATINGS_FORM_SEND", $url . $sep . 'inr=send');
$t->parse('RATINGS.NOTVOTED');
}
else
{
$t->parse('RATINGS.VOTED');
}
$t->parse('RATINGS');
$res = $t->text('RATINGS');
return array($res, '');
}
/**
* Returns stars image for user level
*
* @param int $level User level
* @return unknown
*/
function sed_build_stars($level)
{
global $skin;
if($level>0 and $level<100)
{
return '<img src="skins/'.$skin.'/img/system/stars'.(floor($level/10)+1).'.gif" alt="" />';
}
else
{
return '';
}
}
/**
* Returns time gap between 2 dates
*
* @param int $t1 Stamp 1
* @param int $t2 Stamp2
* @return string
*/
function sed_build_timegap($t1,$t2)
{
global $L;
$gap = $t2 - $t1;
if($gap<=0 || !$t2 || $gap>94608000)
{
$result = '';
}
elseif($gap<60)
{
$result = sed_declension($gap,$L['Seconds']);
}
elseif($gap<3600)
{
$gap = floor($gap/60);
$result = sed_declension($gap,$L['Minutes']);
}
elseif($gap<86400)
{
$gap1 = floor($gap/3600);
$gap2 = floor(($gap-$gap1*3600)/60);
$result = sed_declension($gap1,$L['Hours']).' ';
if ($gap2>0)
{
$result .= sed_declension($gap2,$L['Minutes']);
}
}
else
{
$gap = floor($gap/86400);
$result = sed_declension($gap,$L['Days']);
}
return $result;
}
/**
* Returns user timezone offset
*
* @param int $tz Timezone
* @return string
*/
function sed_build_timezone($tz)
{
global $L;
$result = 'GMT';
$result .= sed_declension($tz, $L['Hours']);
return $result;
}
/**
* Returns link for URL
*
* @param string $text URL
* @param int $maxlen Max. allowed length
* @return unknown
*/
function sed_build_url($text, $maxlen=64)
{
global $cfg;
if(!empty($text))
{
if(mb_strpos($text, 'http://') !== 0)
{
$text='http://'. $text;
}
$text = htmlspecialchars($text);
$text = '<a href="'.$text.'">'.sed_cutstring($text, $maxlen).'</a>';
}
return $text;
}
/**
* Returns link to user profile
*
* @param int $id User ID
* @param string $user User name
* @return string
*/
function sed_build_user($id, $user)
{
global $cfg;
if($id == 0 && !empty($user))
{
return $user;
}
elseif($id == 0)
{
return '';
}
else
{
return (!empty($user)) ? '<a href="'.sed_url('users', 'm=details&id='.$id.'&u='.$user).'">'.$user.'</a>' : '?';
}
}
/**
* Returns user avatar image
*
* @param string $image Image src
* @return string
*/
function sed_build_userimage($image, $type='none')
{
if($type == 'avatar')
{
if(empty($image))
{
$image = 'datas/defaultav/blank.png';
}
return '<img src="'.$image.'" alt="" class="avatar" />';
}
elseif($type == 'photo')
{
if(!empty($image))
{
return '<img src="'.$image.'" alt="" class="photo" />';
}
}
elseif($type == 'sig')
{
if(!empty($image))
{
return '<img src="'.$image.'" alt="" class="signature" />';
}
}
else
{
if(!empty($image))
{
return '<img src="'.$image.'" alt="" />';
}
}
}
/**
* Renders user signature text
*
* @param string $text Signature text
* @return string
*/
function sed_build_usertext($text)
{
global $cfg;
if (!$cfg['usertextimg'])
{
$bbcodes_img = array(
'\[img\]([^\[]*)\[/img\]' => '',
'\[thumb=([^\[]*)\[/thumb\]' => '',
'\[t=([^\[]*)\[/t\]' => '',
'\[list\]' => '',
'\[style=([^\[]*)\]' => '',
'\[quote' => '',
'\[code' => ''
);
foreach($bbcodes_img as $bbcode => $bbcodehtml)
{
$text = preg_replace("#$bbcode#i", $bbcodehtml, $text);
}
}
return sed_parse($text, $cfg['parsebbcodeusertext'], $cfg['parsesmiliesusertext'], 1);
}
/*
* ================================ Cache Subsystem ================================
*/
// TODO scheduled for complete removal and replacement with new cache system
/**
* Clears cache item
*
* @param string $name Item name
* @return bool
*/
function sed_cache_clear($name)
{
global $db_cache;
sed_sql_query("DELETE FROM $db_cache WHERE c_name='$name'");
return(TRUE);
}
/**
* Clears cache completely
*
* @return bool
*/
function sed_cache_clearall()
{
global $db_cache;
sed_sql_query("DELETE FROM $db_cache");
return TRUE;
}
/**
* Clears HTML-cache
*
* @todo Add trigger support here to clean non-standard html fields
* @return bool
*/
function sed_cache_clearhtml()
{
global $db_pages, $db_forum_posts, $db_pm;
$res = TRUE;
$res &= sed_sql_query("UPDATE $db_pages SET page_html=''");
$res &= sed_sql_query("UPDATE $db_forum_posts SET fp_html=''");
$res &= sed_sql_query("UPDATE $db_pm SET pm_html = ''");
return $res;
}
/**
* Fetches cache value
*
* @param string $name Item name
* @return mixed
*/
function sed_cache_get($name)
{
global $cfg, $sys, $db_cache;
if (!$cfg['cache'])
{ return FALSE; }
$sql = sed_sql_query("SELECT c_value FROM $db_cache WHERE c_name='$name' AND c_expire>'".$sys['now']."'");
if ($row = sed_sql_fetcharray($sql))
{ return(unserialize($row['c_value'])); }
else
{ return(FALSE); }
}
/**
* Get all cache data and import it into global scope
*
* @param int $auto Only with autoload flag
* @return mixed
*/
function sed_cache_getall($auto = 1)
{
global $cfg, $sys, $db_cache;
if (!$cfg['cache'])
{ return FALSE; }
$sql = sed_sql_query("DELETE FROM $db_cache WHERE c_expire<'".$sys['now']."'");
if ($auto)
{ $sql = sed_sql_query("SELECT c_name, c_value FROM $db_cache WHERE c_auto=1"); }
else
{ $sql = sed_sql_query("SELECT c_name, c_value FROM $db_cache"); }
if (sed_sql_numrows($sql)>0)
{ return($sql); }
else
{ return(FALSE); }
}
/**
* Puts an item into cache
*
* @param string $name Item name
* @param mixed $value Item value
* @param int $expire Expires in seconds
* @param int $auto Autload flag
* @return bool
*/
function sed_cache_store($name,$value,$expire,$auto="1")
{
global $db_cache, $sys, $cfg;
if (!$cfg['cache'])
{ return(FALSE); }
$sql = sed_sql_query("REPLACE INTO $db_cache (c_name, c_value, c_expire, c_auto) VALUES ('$name', '".sed_sql_prep(serialize($value))."', '".($expire + $sys['now'])."', '$auto')");
return(TRUE);
}
/**
* Makes HTML sequences safe
*
* @deprecated
* @param string $text Source string
* @return string
*/
function sed_cc($text)
{
/*$text = str_replace(
array('{', '<', '>' , '$', '\'', '"', '\\', '&', ' '),
array('{', '<', '>', '$', ''', '"', '\', '&amp;', '&nbsp;'), $text);
return $text;*/
return htmlspecialchars($text);
}
/**
* Unregisters globals if globals are On
* @see http://www.php.net/manual/en/faq.misc.php#faq.misc.registerglobals
*/
function sed_unregister_globals()
{
if (!ini_get('register_globals'))
{
return;
}
// Might want to change this perhaps to a nicer error
if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS']))
{
die('GLOBALS overwrite attempt detected');
}
// Variables that shouldn't be unset
$noUnset = array('GLOBALS', '_GET',
'_POST', '_COOKIE',
'_REQUEST', '_SERVER',
'_ENV', '_FILES');
$input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES,
isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
foreach ($input as $k => $v)
{
if (!in_array($k, $noUnset) && isset($GLOBALS[$k]))
{
unset($GLOBALS[$k]);
}
}
}
/**
* Checks GET anti-XSS parameter
*
* @return bool
*/
function sed_check_xg()
{
global $sys;
$x = sed_import('x', 'G', 'ALP');
if ($x != $sys['xk'] && (empty($sys['xk_prev']) || $x != $sys['xk_prev']))
{
sed_redirect(sed_url('message', 'msg=950', '', true));
return false;
}
return true;
}
/**
* Checks POST anti-XSS parameter
*
* @return bool
*/
function sed_check_xp()
{
return (defined('SED_NO_ANTIXSS') || defined('SED_AUTH')) ?
($_SERVER['REQUEST_METHOD'] == 'POST') : isset($_POST['x']);
}
/**
* Hashes a value with given salt and specified hash algo.
*
* @global array $sed_hash_func
* @param string $data Data to be hash-protected
* @param string $salt Hashing salt, usually a random value
* @param string $algo Hashing algo name, must be registered in $sed_hash_funcs
* @return string Hashed value
*/
function sed_hash($data, $salt = '', $algo = 'sha256')
{
global $cfg, $sed_hash_funcs;
if (isset($cfg['hashsalt']) && !empty($cfg['hashsalt']))
{
// Extra salt for extremely secure sites
$salt .= $cfg['hashsalt'];
}
$func = (in_array($algo, $sed_hash_funcs) && function_exists('sed_hash_' . $algo)) ? 'sed_hash_' . $algo : 'sed_hash_sha256';
return $func($data, $salt);
}
/**
* Returns the list of available hash algos for use with configs.
*
* @global array $sed_hash_func
* @return array
*/
function sed_hash_funcs()
{
global $sed_hash_funcs;
return $sed_hash_funcs;
}
/**
* Simple MD5 hash wrapper. Old passwords use this func.
*
* @param string $data Data to be hashed
* @param string $salt Hashing salt, usually a random value
* @return string MD5 hash of the data
*/
function sed_hash_md5($data, $salt)
{
return md5($data . $salt);
}
/**
* SHA1 hash func for use with sed_hash().
*
* @param string $data Data to be hashed
* @param string $salt Hashing salt, usually a random value
* @return string SHA1 hash of the data
*/
function sed_hash_sha1($data, $salt)
{
return hash('sha1', $data . $salt);
}
/**
* SHA256 hash func for use with sed_hash(). Default since Cotonti 0.9.11.
*
* @param string $data Data to be hashed
* @param string $salt Hashing salt, usually a random value
* @return string SHA256 hash of the data
*/
function sed_hash_sha256($data, $salt)
{
return hash('sha256', $data . $salt);
}
/**
* Truncates a post and makes sure parsing is correct
*
* @param string $text Post text
* @param int $max_chars Max. length
* @param bool $parse_bbcodes Parse bbcodes
* @return unknown
*/
function sed_cutpost($text, $max_chars, $parse_bbcodes = true)
{
$text = $max_chars == 0 ? $text : sed_cutstring(strip_tags($text), $max_chars);
// Fix partial cuttoff
$text = preg_replace('#\[[^\]]*?$#', '...', $text);
// Parse the BB-codes or skip them
if($parse_bbcodes)
{
// Parse it
$text = sed_parse($text);
}
else $text = preg_replace('#\[[^\]]+?\]#', '', $text);
return $text;
}
/**
* Truncates a string
*
* @param string $res Source string
* @param int $l Length
* @return unknown
*/
function sed_cutstring($res, $l)
{
global $cfg;
if(mb_strlen($res)>$l)
{
$res = mb_substr($res, 0, ($l-3)).'...';
}
return $res;
}
/**
* Creates image thumbnail
*
* @param string $img_big Original image path
* @param string $img_small Thumbnail path
* @param int $small_x Thumbnail width
* @param int $small_y Thumbnail height
* @param bool $keepratio Keep original ratio
* @param string $extension Image type
* @param string $filen Original file name
* @param int $fsize File size in kB
* @param string $textcolor Text color
* @param int $textsize Text size
* @param string $bgcolor Background color
* @param int $bordersize Border thickness
* @param int $jpegquality JPEG quality in %
* @param string $dim_priority Resize priority dimension
*/
function sed_createthumb($img_big, $img_small, $small_x, $small_y, $keepratio, $extension, $filen, $fsize, $textcolor, $textsize, $bgcolor, $bordersize, $jpegquality, $dim_priority="Width")
{
if (!function_exists('gd_info'))
{ return; }
global $cfg;
$gd_supported = array('jpg', 'jpeg', 'png', 'gif');
switch($extension)
{
case 'gif':
$source = imagecreatefromgif($img_big);
break;
case 'png':
$source = imagecreatefrompng($img_big);
break;
default:
$source = imagecreatefromjpeg($img_big);
break;
}
$big_x = imagesx($source);
$big_y = imagesy($source);
if (!$keepratio)
{
$thumb_x = $small_x;
$thumb_y = $small_y;
}
elseif ($dim_priority=="Width")
{
$thumb_x = $small_x;
$thumb_y = floor($big_y * ($small_x / $big_x));
}
else
{
$thumb_x = floor($big_x * ($small_y / $big_y));
$thumb_y = $small_y;
}
if ($textsize==0)
{
if ($cfg['th_amode']=='GD1')
{ $new = imagecreate($thumb_x+$bordersize*2, $thumb_y+$bordersize*2); }
else
{ $new = imagecreatetruecolor($thumb_x+$bordersize*2, $thumb_y+$bordersize*2); }
$background_color = imagecolorallocate ($new, $bgcolor[0], $bgcolor[1] ,$bgcolor[2]);
imagefilledrectangle ($new, 0,0, $thumb_x+$bordersize*2, $thumb_y+$bordersize*2, $background_color);
if ($cfg['th_amode']=='GD1')
{ imagecopyresized($new, $source, $bordersize, $bordersize, 0, 0, $thumb_x, $thumb_y, $big_x, $big_y); }
else
{ imagecopyresampled($new, $source, $bordersize, $bordersize, 0, 0, $thumb_x, $thumb_y, $big_x, $big_y); }
}
else
{
if ($cfg['th_amode']=='GD1')
{ $new = imagecreate($thumb_x+$bordersize*2, $thumb_y+$bordersize*2+$textsize*3.5+6); }
else
{ $new = imagecreatetruecolor($thumb_x+$bordersize*2, $thumb_y+$bordersize*2+$textsize*3.5+6); }
$background_color = imagecolorallocate($new, $bgcolor[0], $bgcolor[1] ,$bgcolor[2]);
imagefilledrectangle ($new, 0,0, $thumb_x+$bordersize*2, $thumb_y+$bordersize*2+$textsize*4+14, $background_color);
$text_color = imagecolorallocate($new, $textcolor[0],$textcolor[1],$textcolor[2]);
if ($cfg['th_amode']=='GD1')
{ imagecopyresized($new, $source, $bordersize, $bordersize, 0, 0, $thumb_x, $thumb_y, $big_x, $big_y); }
else
{ imagecopyresampled($new, $source, $bordersize, $bordersize, 0, 0, $thumb_x, $thumb_y, $big_x, $big_y); }
imagestring ($new, $textsize, $bordersize, $thumb_y+$bordersize+$textsize+1, $big_x."x".$big_y." ".$fsize."kb", $text_color);
}
switch($extension)
{
case 'gif':
imagegif($new, $img_small);
break;
case 'png':
imagepng($new, $img_small);
break;
default:
imagejpeg($new, $img_small, $jpegquality);
break;
}
imagedestroy($new);
imagedestroy($source);
}
/**
* Terminates script execution and performs redirect
*
* @param bool $cond Really die?
* @return bool
*/
function sed_die($cond=TRUE)
{
if ($cond)
{
header("Location: " . SED_ABSOLUTE_URL . sed_url('message', "msg=950", '', true));
exit;
}
return FALSE;
}
/**
* Terminates script execution with fatal error
*
* @param string $text Reason
* @param string $title Message title
*/
function sed_diefatal($text='Reason is unknown.', $title='Fatal error')
{
global $cfg;
if (defined('SED_DEBUG') && SED_DEBUG)
{
echo '<br /><pre>';
debug_print_backtrace();
echo '</pre>';
}
$disp = "<strong><a href=\"".$cfg['mainurl']."\">".$cfg['maintitle']."</a></strong><br />";
$disp .= @date('Y-m-d H:i').'<br />'.$title.' : '.$text;
die($disp);
}
/**
* Terminates with "disabled" error
*
* @param unknown_type $disabled
*/
function sed_dieifdisabled($disabled)
{
if ($disabled)
{
header("Location: " . SED_ABSOLUTE_URL . sed_url('message', "msg=940", '', true));
exit;
}
}
/**
* Checks a file to be sure it is valid
*
* @param string $path File path
* @param string $name File name
* @param string $ext File extension
* @return bool
*/
function sed_file_check($path, $name, $ext)
{
global $L, $cfg;
if($cfg['pfsfilecheck'])
{
require('./datas/mimetype.php');
$fcheck = FALSE;
if(in_array($ext, array('jpg', 'jpeg', 'png', 'gif')))
{
switch($ext)
{
case 'gif':
$fcheck = @imagecreatefromgif($path);
break;
case 'png':
$fcheck = @imagecreatefrompng($path);
break;
default:
$fcheck = @imagecreatefromjpeg($path);
break;
}
$fcheck = $fcheck !== FALSE;
}
else
{
if(!empty($mime_type[$ext]))
{
foreach($mime_type[$ext] as $mime)
{
$content = file_get_contents($path, 0, NULL, $mime[3], $mime[4]);
$content = ($mime[2]) ? bin2hex($content) : $content;
$mime[1] = ($mime[2]) ? strtolower($mime[1]) : $mime[1];
$i++;
if ($content == $mime[1])
{
$fcheck = TRUE;
break;
}
}
}
else
{
$fcheck = ($cfg['pfsnomimepass']) ? 1 : 2;
sed_log(sprintf($L['pfs_filechecknomime'], $ext, $name), 'sec');
}
}
if(!$fcheck)
{
sed_log(sprintf($L['pfs_filecheckfail'], $ext, $name), 'sec');
}
}
else
{
$fcheck = true;
}
return($fcheck);
}
/*
* ==================================== Forum Functions ==================================
*/
/**
* Gets details for forum section
*
* @param int $id Section ID
* @return mixed
*/
function sed_forum_info($id)
{
global $db_forum_sections;
$sql = sed_sql_query("SELECT * FROM $db_forum_sections WHERE fs_id='$id'");
if($res = sed_sql_fetcharray($sql))
{
return ($res);
}
else
{
return ('');
}
}
/**
* Moves outdated topics to trash
*
* @param string $mode Selection criteria
* @param int $section Section
* @param int $param Selection parameter value
* @return int
*/
function sed_forum_prunetopics($mode, $section, $param)
{
global $cfg, $sys, $db_forum_topics, $db_forum_posts, $db_forum_sections, $db_polls, $L;
$num = 0;
$num1 = 0;
switch ($mode)
{
case 'updated':
$limit = $sys['now'] - ($param*86400);
$sql1 = sed_sql_query("SELECT * FROM $db_forum_topics WHERE ft_sectionid='$section' AND ft_updated<'$limit' AND ft_sticky='0'");
break;
case 'single':
$sql1 = sed_sql_query("SELECT * FROM $db_forum_topics WHERE ft_sectionid='$section' AND ft_id='$param'");
break;
}
if (sed_sql_numrows($sql1)>0)
{
while ($row1 = sed_sql_fetchassoc($sql1))
{
$q = $row1['ft_id'];
if ($cfg['trash_forum'])
{
$sql = sed_sql_query("SELECT * FROM $db_forum_posts WHERE fp_topicid='$q' ORDER BY fp_id DESC");
while ($row = sed_sql_fetchassoc($sql))
{ sed_trash_put('forumpost', $L['Post']." #".$row['fp_id']." from topic #".$q, "p".$row['fp_id']."-q".$q, $row); }
}
$sql = sed_sql_query("DELETE FROM $db_forum_posts WHERE fp_topicid='$q'");
$num += sed_sql_affectedrows();
if ($cfg['trash_forum'])
{
$sql = sed_sql_query("SELECT * FROM $db_forum_topics WHERE ft_id='$q'");
while ($row = sed_sql_fetchassoc($sql))
{ sed_trash_put('forumtopic', $L['Topic']." #".$q." (no post left)", "q".$q, $row); }
}
$sql = sed_sql_query("DELETE FROM $db_forum_topics WHERE ft_id='$q'");
$num1 += sed_sql_affectedrows();
$sql = sed_sql_query("SELECT poll_id FROM $db_polls WHERE poll_type='forum' AND poll_code='$q' LIMIT 1");
if ($row = sed_sql_fetcharray($sql))
{
$id=$row['poll_id'];
global $db_polls_options, $db_polls_voters;
$sql = sed_sql_query("DELETE FROM $db_polls WHERE poll_id=".$id);
$sql = sed_sql_query("DELETE FROM $db_polls_options WHERE po_pollid=".$id);
$sql = sed_sql_query("DELETE FROM $db_polls_voters WHERE pv_pollid=".$id);
}
}
$sql = sed_sql_query("DELETE FROM $db_forum_topics WHERE ft_movedto='$q'");
$sql = sed_sql_query("UPDATE $db_forum_sections SET fs_topiccount=fs_topiccount-'$num1', fs_postcount=fs_postcount-'$num', fs_topiccount_pruned=fs_topiccount_pruned+'$num1', fs_postcount_pruned=fs_postcount_pruned+'$num' WHERE fs_id='$section'");
$sql = sed_sql_query("SELECT fs_masterid FROM $db_forum_sections WHERE fs_id='$section' ");
$row = sed_sql_fetcharray($sql);
$fs_masterid = $row['fs_masterid'];
$sql = ($fs_masterid>0) ? sed_sql_query("UPDATE $db_forum_sections SET fs_topiccount=fs_topiccount-'$num1', fs_postcount=fs_postcount-'$num', fs_topiccount_pruned=fs_topiccount_pruned+'$num1', fs_postcount_pruned=fs_postcount_pruned+'$num' WHERE fs_id='$fs_masterid'") : '';
}
$num1 = ($num1=='') ? '0' : $num1;
return($num1);
}
/**
* Changes last message for the section
*
* @param int $id Section ID
*/
function sed_forum_sectionsetlast($id)
{
global $db_forum_topics, $db_forum_sections;
$sql = sed_sql_query("SELECT ft_id, ft_lastposterid, ft_lastpostername, ft_updated, ft_title, ft_poll FROM $db_forum_topics WHERE ft_sectionid='$id' AND ft_movedto='0' and ft_mode='0' ORDER BY ft_updated DESC LIMIT 1");
$row = sed_sql_fetcharray($sql);
$sql = sed_sql_query("UPDATE $db_forum_sections SET fs_lt_id=".(int)$row['ft_id'].", fs_lt_title='".sed_sql_prep($row['ft_title'])."', fs_lt_date=".(int)$row['ft_updated'].", fs_lt_posterid=".(int)$row['ft_lastposterid'].", fs_lt_postername='".sed_sql_prep($row['ft_lastpostername'])."' WHERE fs_id='$id'");
$sqll = sed_sql_query("SELECT fs_masterid FROM $db_forum_sections WHERE fs_id='$id' ");
$roww = sed_sql_fetcharray($sqll);
$fs_masterid = $roww['fs_masterid'];
$sql = ($fs_masterid>0) ? sed_sql_query("UPDATE $db_forum_sections SET fs_lt_id=".(int)$row['ft_id'].", fs_lt_title='".sed_sql_prep($row['ft_title'])."', fs_lt_date=".(int)$row['ft_updated'].", fs_lt_posterid=".(int)$row['ft_lastposterid'].", fs_lt_postername='".sed_sql_prep($row['ft_lastpostername'])."' WHERE fs_id='$fs_masterid'") : '';
}
/**
* Returns a list of plugins registered for a hook
*
* @param string $hook Hook name
* @param string $cond Permissions
* @return array
*/
function sed_getextplugins($hook, $cond='R')
{
global $sed_plugins, $usr;
if (is_array($sed_plugins))
{
foreach($sed_plugins as $i => $k)
{
if($k['pl_hook']==$hook && sed_auth('plug', $k['pl_code'], $cond))
{
$extplugins[$i] = $k;
}
}
}
return $extplugins;
}
/**
* Returns number of comments for item
*
* @param string $code Item code
* @return int
*/
function sed_get_comcount($code)
{
global $db_com;
$sql = sed_sql_query("SELECT DISTINCT com_code, COUNT(*) FROM $db_com WHERE com_code='$code' GROUP BY com_code");
if ($row = sed_sql_fetcharray($sql))
{
return (int) $row['COUNT(*)'];
}
else
{
return 0;
}
}
/**
* Returns maximum size for uploaded file, in KB (allowed in php.ini, and may be allowed in .htaccess)
*
* @return int
*/
function sed_get_uploadmax()
{
static $par_a = array('upload_max_filesize', 'post_max_size', 'memory_limit');
static $opt_a = array('G' => 1073741824, 'M' => 1048576, 'K' => 1024);
$val_a = array();
foreach ($par_a as $par)
{
$val = ini_get($par);
$opt = strtoupper($val[strlen($val) - 1]);
$val = isset($opt_a[$opt]) ? $val * $opt_a[$opt] : (int)$val;
if ($val > 0)
{
$val_a[] = $val;
}
}
return floor(min($val_a) / 1024); // KB
}
/**
* Imports data from the outer world
*
* @param string $name Variable name
* @param string $source Source type: G (GET), P (POST), C (COOKIE) or D (variable filtering)
* @param string $filter Filter type
* @param int $maxlen Length limit
* @param bool $dieonerror Die with fatal error on wrong input
* @return mixed
*/
function sed_import($name, $source, $filter, $maxlen=0, $dieonerror=FALSE)
{
switch($source)
{
case 'G':
$v = (isset($_GET[$name])) ? $_GET[$name] : NULL;
$log = TRUE;
break;
case 'P':
$v = (isset($_POST[$name])) ? $_POST[$name] : NULL;
$log = TRUE;
if ($filter=='ARR') { return($v); }
break;
case 'R':
$v = (isset($_REQUEST[$name])) ? $_REQUEST[$name] : NULL;
$log = TRUE;
break;
case 'C':
$v = (isset($_COOKIE[$name])) ? $_COOKIE[$name] : NULL;
$log = TRUE;
break;
case 'D':
$v = $name;
$log = FALSE;
break;
default:
sed_diefatal('Unknown source for a variable : <br />Name = '.$name.'<br />Source = '.$source.' ? (must be G, P, C or D)');
break;
}
if (MQGPC && ($source=='G' || $source=='P' || $source=='C') )
{
$v = stripslashes($v);
}
if ($v=='' || $v == NULL)
{
return($v);
}
if ($maxlen>0)
{
$v = mb_substr($v, 0, $maxlen);
}
$pass = FALSE;
$defret = NULL;
$filter = ($filter=='STX') ? 'TXT' : $filter;
switch($filter)
{
case 'INT':
if (is_numeric($v) && floor($v)==$v)
{
$pass = TRUE;
}
break;
case 'NUM':
if(is_numeric($v))
{
$pass = TRUE;
}
break;
case 'TXT':
$v = trim($v);
if (mb_strpos($v, '<')===FALSE)
{
$pass = TRUE;
}
else
{
$defret = str_replace('<', '<', $v);
}
break;
case 'SLU':
$v = trim($v);
$f = preg_replace('/[^a-zA-Z0-9_=\/]/', '', $v);
if($v == $f)
{
$pass = TRUE;
}
else
{
$defret = '';
}
break;
case 'ALP':
$v = trim($v);
$f = sed_alphaonly($v);
if($v == $f)
{
$pass = TRUE;
}
else
{
$defret = $f;
}
break;
case 'PSW':
$v = trim($v);
$f = preg_replace('#[\'"&<>]#', '', $v);
$f = mb_substr($f, 0 ,32);
if ($v == $f)
{
$pass = TRUE;
}
else
{
$defret = $f;
}
break;
case 'HTM':
$v = trim($v);
$pass = TRUE;
break;
case 'ARR':
$pass = TRUE;
break;
case 'BOL':
if($v == '1' || $v == 'on')
{
$pass = TRUE;
$v = '1';
}
elseif($v=='0' || $v=='off')
{
$pass = TRUE;
$v = '0';
}
else
{
$defret = '0';
}
break;
case 'LVL':
if(is_numeric($v) && $v >= 0 && $v <= 100 && floor($v)==$v)
{
$pass = TRUE;
}
else
{
$defret = NULL;
}
break;
case 'NOC':
$pass = TRUE;
break;
default:
sed_diefatal('Unknown filter for a variable : <br />Var = '.$cv_v.'<br />Filter = '.$filter.' ?');
break;
}
$v = preg_replace('/(&#\d+)(?![\d;])/', '$1;', $v);
if($pass)
{
return($v);
}
else
{
if($log)
{
sed_log_sed_import($source, $filter, $name, $v);
}
if($dieonerror)
{
sed_diefatal('Wrong input.');
}
else
{
return($defret);
}
}
}
/**
* Extract info from SED file headers
*
* @param string $file File path
* @param string $limiter Tag name
* @param int $maxsize Max header size
* @return array
*/
function sed_infoget($file, $limiter='SED', $maxsize=32768)
{
$result = array();
if($fp = @fopen($file, 'r'))
{
$limiter_begin = "[BEGIN_".$limiter."]";
$limiter_end = "[END_".$limiter."]";
$data = fread($fp, $maxsize);
$begin = mb_strpos($data, $limiter_begin);
$end = mb_strpos($data, $limiter_end);
if ($end>$begin && $begin>0)
{
$lines = mb_substr($data, $begin+8+mb_strlen($limiter), $end-$begin-mb_strlen($limiter)-8);
$lines = explode ("\n",$lines);
foreach ($lines as $k => $line)
{
$linex = explode ("=", $line);
$ii=1;
while (!empty($linex[$ii]))
{
$result[$linex[0]] .= trim($linex[$ii]);
$ii++;
}
}
}
else
{ $result['Error'] = 'Warning: No tags found in '.$file; }
}
else
{ $result['Error'] = 'Error: File '.$file.' is missing!'; }
@fclose($fp);
return ($result);
}
/**
* Outputs standard javascript
*
* @param string $more Extra javascript
* @return string
*/
function sed_javascript($more='')
{
global $cfg, $lang;
if($cfg['jquery'])
{
$result .= '<script type="text/javascript" src="js/jquery.js"></script>';
}
$result .= '<script type="text/javascript" src="js/base.js"></script>';
if(!empty($more))
{
$result .= '<script type="text/javascript">
//<![CDATA[
'.$more.'
//]]>
</script>';
}
return $result;
}
/**
* Returns a language file path for a plugin or FALSE on error.
*
* @param string $name Plugin name
* @param bool $core Use core module rather than a plugin
* @return bool
*/
function sed_langfile($name, $core = false, $loadlang=false)
{
global $cfg, $lang;
if($loadlang)
{
$lang = $loadlang;
}
if($core)
{
// For module support, comming in N-0.1.0
if(@file_exists($cfg['system_dir']."/lang/$lang/$name.lang.php") && $loadlang!='en')
return $cfg['system_dir']."/lang/$lang/$name.lang.php";
else
return $cfg['system_dir']."/lang/en/$name.lang.php";
}
else
{
if(@file_exists($cfg['plugins_dir']."/$name/lang/$name.$lang.lang.php") && $loadlang!='en')
return $cfg['plugins_dir']."/$name/lang/$name.$lang.lang.php";
else
return $cfg['plugins_dir']."/$name/lang/$name.en.lang.php";
}
}
/**
* Load smilies from current pack
*/
function sed_load_smilies()
{
global $sed_smilies;
$sed_smilies = array();
if(!file_exists('./images/smilies/set.js')) return;
// A simple JSON parser and decoder
$json = '';
$started = false;
$fp = fopen('./images/smilies/set.js', 'r');
$i = -1;
$prio = array();
$code = array();
$file = array();
while(!feof($fp))
{
$line = fgets($fp);
if($line == '];') break;
if($started)
{
$line = trim($line, " \t\r\n");
if($line == '{')
{
$i++;
}
elseif($line != '},')
{
if(preg_match('#^(\w+)\s*:\s*"?(.+?)"?,?$#', $line, $m))
{
switch($m[1])
{
case 'prio':
$prio[$i] = intval($m[2]);
break;
case 'code':
$code[$i] = str_replace('\\\\', '\\', $m[2]);
break;
case 'file':
$file[$i] = $m[2];
break;
}
}
}
}
elseif (mb_strpos($line, 'smileSet') !== false)
{
$started = true;
}
}
fclose($fp);
// Sort the result
array_multisort($prio, SORT_ASC, $code, $file);
$cnt = count($code);
for($i = 0; $i < $cnt; $i++)
{
$sed_smilies[$i] = array(
'code' => $code[$i],
'file' => $file[$i]
);
}
}
/**
* Loads comlete category structure into array
*
* @return array
*/
function sed_load_structure()
{
global $db_structure, $cfg, $L;
$res = array();
$sql = sed_sql_query("SELECT * FROM $db_structure ORDER BY structure_path ASC");
while ($row = sed_sql_fetcharray($sql))
{
if (!empty($row['structure_icon']))
{
$row['structure_icon'] = '<img src="'.$row['structure_icon'].'" alt="'.htmlspecialchars($row['structure_title']).'" title="'.htmlspecialchars($row['structure_title']).'" />';
}
$path2 = mb_strrpos($row['structure_path'], '.');
$row['structure_tpl'] = (empty($row['structure_tpl'])) ? $row['structure_code'] : $row['structure_tpl'];
if ($path2>0)
{
$path1 = mb_substr($row['structure_path'],0,($path2));
$path[$row['structure_path']] = $path[$path1].'.'.$row['structure_code'];
$tpath[$row['structure_path']] = $tpath[$path1].' '.$cfg['separator'].' '.$row['structure_title'];
$row['structure_tpl'] = ($row['structure_tpl']=='same_as_parent') ? $parent_tpl : $row['structure_tpl'];
}
else
{
$path[$row['structure_path']] = $row['structure_code'];
$tpath[$row['structure_path']] = $row['structure_title'];
}
$order = explode('.',$row['structure_order']);
$parent_tpl = $row['structure_tpl'];
$res[$row['structure_code']] = array (
'path' => $path[$row['structure_path']],
'tpath' => $tpath[$row['structure_path']],
'rpath' => $row['structure_path'],
'tpl' => $row['structure_tpl'],
'title' => $row['structure_title'],
'desc' => $row['structure_desc'],
'icon' => $row['structure_icon'],
'group' => $row['structure_group'],
'com' => $row['structure_comments'],
'ratings' => $row['structure_ratings'],
'order' => $order[0],
'way' => $order[1]
);
}
return($res);
}
/**
* Loads complete forum structure into array
*
* @return array
*/
function sed_load_forum_structure()
{
global $db_forum_structure, $cfg, $L;
$res = array();
$sql = sed_sql_query("SELECT * FROM $db_forum_structure ORDER BY fn_path ASC");
while ($row = sed_sql_fetcharray($sql))
{
if (!empty($row['fn_icon']))
{ $row['fn_icon'] = "<img src=\"".$row['fn_icon']."\" alt=\"\" />"; }
$path2 = mb_strrpos($row['fn_path'], '.');
$row['fn_tpl'] = (empty($row['fn_tpl'])) ? $row['fn_code'] : $row['fn_tpl'];
if ($path2>0)
{
$path1 = mb_substr($row['fn_path'],0,($path2));
$path[$row['fn_path']] = $path[$path1].'.'.$row['fn_code'];
$tpath[$row['fn_path']] = $tpath[$path1].' '.$cfg['separator'].' '.$row['fn_title'];
$row['fn_tpl'] = ($row['fn_tpl']=='same_as_parent') ? $parent_tpl : $row['fn_tpl'];
}
else
{
$path[$row['fn_path']] = $row['fn_code'];
$tpath[$row['fn_path']] = $row['fn_title'];
}
$parent_tpl = $row['fn_tpl'];
$res[$row['fn_code']] = array (
'path' => $path[$row['fn_path']],
'tpath' => $tpath[$row['fn_path']],
'rpath' => $row['fn_path'],
'tpl' => $row['fn_tpl'],
'title' => $row['fn_title'],
'desc' => $row['fn_desc'],
'icon' => $row['fn_icon'],
'defstate' => $row['fn_defstate']
);
}
return($res);
}
/**
* Logs an event
*
* @param string $text Event description
* @param string $group Event group
*/
function sed_log($text, $group='def')
{
global $db_logger, $sys, $usr, $_SERVER;
$sql = sed_sql_query("INSERT INTO $db_logger (log_date, log_ip, log_name, log_group, log_text) VALUES (".(int)$sys['now_offset'].", '".$usr['ip']."', '".sed_sql_prep($usr['name'])."', '$group', '".sed_sql_prep($text.' - '.$_SERVER['REQUEST_URI'])."')");
}
/**
* Logs wrong input
*
* @param string $s Source type
* @param string $e Filter type
* @param string $v Variable name
* @param string $o Value
*/
function sed_log_sed_import($s, $e, $v, $o)
{
$text = "A variable type check failed, expecting ".$s."/".$e." for '".$v."' : ".$o;
sed_log($text, 'sec');
}
/**
* Sends mail with standard PHP mail()
*
* @global $cfg
* @param string $fmail Recipient
* @param string $subject Subject
* @param string $body Message body
* @param string $headers Message headers
* @param string $additional_parameters Additional parameters passed to sendmail
* @return bool
*/
function sed_mail($fmail, $subject, $body, $headers='', $additional_parameters = null)
{
global $cfg;
if (function_exists('sed_mail_custom'))
{
return sed_mail_custom($fmail, $subject, $body, $headers, $additional_parameters);
}
if(empty($fmail))
{
return(FALSE);
}
else
{
$headers = (empty($headers)) ? "From: \"".mb_encode_mimeheader($cfg['maintitle'], $cfg['charset'], 'Q')."\" <".$cfg['adminemail'].">\n"."Reply-To: <".$cfg['adminemail'].">\n" : $headers;
$body .= "\n\n".$cfg['maintitle']." - ".$cfg['mainurl']."\n".$cfg['subtitle'];
if($cfg['charset'] != 'us-ascii')
{
$headers .= "Content-Type: text/plain; charset=".$cfg['charset']."\n";
$headers .= "Content-Transfer-Encoding: 8bit\n";
$subject = mb_encode_mimeheader($subject, $cfg['charset'], 'B', "\n");
}
if(ini_get('safe_mode'))
{
mail($fmail, $subject, $body, $headers);
}
else
{
mail($fmail, $subject, $body, $headers, $additional_parameters);
}
sed_stat_inc('totalmailsent');
return(TRUE);
}
}
/* ------------------ */
// FIXME this function is obsolete, or meta/title generation must be reworked
function sed_htmlmetas()
{
global $cfg;
$contenttype = ($cfg['doctypeid']>2 && $cfg['xmlclient']) ? "application/xhtml+xml" : "text/html";
$result = "<meta http-equiv=\"content-type\" content=\"".$contenttype."; charset=".$cfg['charset']."\" />
<meta name=\"description\" content=\"".$cfg['maintitle']." - ".$cfg['subtitle']."\" />
<meta name=\"keywords\" content=\"".$cfg['metakeywords']."\" />
<meta name=\"generator\" content=\"Cotonti http://www.cotonti.com\" />
<meta http-equiv=\"expires\" content=\"Fri, Apr 01 1974 00:00:00 GMT\" />
<meta http-equiv=\"pragma\" content=\"no-cache\" />
<meta http-equiv=\"cache-control\" content=\"no-cache\" />
<meta http-equiv=\"last-modified\" content=\"".gmdate("D, d M Y H:i:s")." GMT\" />
<link rel=\"shortcut icon\" href=\"favicon.ico\" />
";
return ($result);
}
/**
* Creates UNIX timestamp out of a date
*
* @param int $hour Hours
* @param int $minute Minutes
* @param int $second Seconds
* @param int $month Month
* @param int $date Day of the month
* @param int $year Year
* @return int
*/
function sed_mktime($hour = false, $minute = false, $second = false, $month = false, $date = false, $year = false)
{
if ($hour === false) $hour = date ('G');
if ($minute === false) $minute = date ('i');
if ($second === false) $second = date ('s');
if ($month === false) $month = date ('n');
if ($date === false) $date = date ('j');
if ($year === false) $year = date ('Y');
return mktime ((int) $hour, (int) $minute, (int) $second, (int) $month, (int) $date, (int) $year);
}
/**
* Converts MySQL date into UNIX timestamp
*
* @param string $date Date in MySQL format
* @return int UNIX timestamp
*/
function sed_date2stamp($date)
{
if ($date == '0000-00-00') return 0;
preg_match('#(\d{4})-(\d{2})-(\d{2})#', $date, $m);
return mktime(0, 0, 0, (int) $m[2], (int) $m[3], (int) $m[1]);
}
/**
* Converts UNIX timestamp into MySQL date
*
* @param int $stamp UNIX timestamp
* @return string MySQL date
*/
function sed_stamp2date($stamp)
{
return date('Y-m-d', $stamp);
}
/**
* Standard SED output filters, adds XSS protection to forms
*
* @param unknown_type $output
* @return unknown
*/
function sed_outputfilters($output)
{
global $cfg;
/* === Hook === */
$extp = sed_getextplugins('output');
if (is_array($extp))
{ foreach($extp as $k => $pl) { include_once($cfg['plugins_dir'].'/'.$pl['pl_code'].'/'.$pl['pl_file'].'.php'); } }
/* ==== */
$output = preg_replace('#<form\s+[^>]*method=["\']?post["\']?[^>]*>#i', '$0' . sed_xp(), $output);
return($output);
}
/**
* Renders page navigation bar
*
* @param string $url Basic URL
* @param int $current Current page number
* @param int $entries Total rows
* @param int $perpage Rows per page
* @param string $characters It is symbol for parametre which transfer pagination
* @param string $onclick Name of JavaScript function which it will be specified in parametre OnClick of the link
* @param string $object List of pairs parametre:value through a comma. Use when it is necessary to pass in function $onclick not only value of number of page
* @return string
*/
function sed_pagination($url, $current, $entries, $perpage, $characters = 'd', $onclick = '', $object='')
{
if(function_exists('sed_pagination_custom'))
{
// For custom pagination functions in plugins
return sed_pagination_custom($url, $current, $entries, $perpage, $characters, $onclick, $object);
}
if($entries <= $perpage)
{
return '';
}
$each_side = 3; // Links each side
$address = $url . ((mb_strpos($url, '?') !== false) ? '&' : '?') . $characters . '=';
$totalpages = ceil($entries / $perpage);
$currentpage = floor($current / $perpage) + 1;
$cur_left = $currentpage - $each_side;
if($cur_left < 1) $cur_left = 1;
$cur_right = $currentpage + $each_side;
if($cur_right > $totalpages) $cur_right = $totalpages;
$before = '';
$pages = '';
$after = '';
$i = 1;
$n = 0;
while($i < $cur_left)
{
$k = ($i - 1) * $perpage;
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'='.$k.'\', '.$object.'}; ';
$strlistparam = empty($object) ? $k : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$before .= '<span class="pagenav_pages"><a href="'.$address.$k.'"'.$event.'>'.$i.'</a></span>';
$i *= ($n % 2) ? 2 : 5;
$n++;
}
for($j = $cur_left; $j <= $cur_right; $j++)
{
$k = ($j - 1) * $perpage;
$class = $j == $currentpage ? 'current' : 'pages';
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'='.$k.'\', '.$object.'}; ';
$strlistparam = empty($object) ? $k : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$pages .= '<span class="pagenav_'.$class.'"><a href="'.$address.$k.'"'.$event.'>'.$j.'</a></span>';
}
while($i <= $cur_right)
{
$i *= ($n % 2) ? 2 : 5;
$n++;
}
while($i < $totalpages)
{
$k = ($i - 1) * $perpage;
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'='.$k.'\', '.$object.'}; ';
$strlistparam = empty($object) ? $k : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$after .= '<span class="pagenav_pages"><a href="'.$address.$k.'"'.$event.'>'.$i.'</a></span>';
$i *= ($n % 2) ? 5 : 2;
$n++;
}
$pages = $before . $pages . $after;
return $pages;
}
/**
* Renders page navigation previous/next buttons
*
* @param string $url Basic URL
* @param int $current Current page number
* @param int $entries Total rows
* @param int $perpage Rows per page
* @param bool $res_array Return results as array
* @param string $characters It is symbol for parametre which transfer pagination
* @param string $onclick Name of JavaScript function which it will be specified in parametre OnClick of the link
* @param string $object List of pairs parametre:value through a comma. Use when it is necessary to pass in function $onclick not only value of number of page
* @return mixed
*/
function sed_pagination_pn($url, $current, $entries, $perpage, $res_array = FALSE, $characters = 'd', $onclick = '', $object='')
{
if(function_exists('sed_pagination_pn_custom'))
{
// For custom pagination functions in plugins
return sed_pagination_pn_custom($url, $current, $entries, $perpage, $res_array, $characters, $onclick, $object);
}
global $L;
$address = $url . ((mb_strpos($url, '?') !== false) ? '&' : '?') . $characters . '=';
$totalpages = ceil($entries / $perpage);
$currentpage = floor($current / $perpage) + 1;
if ($current > 0)
{
$prev_n = $current - $perpage;
if ($prev_n < 0) { $prev_n = 0; }
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'='.$prev_n.'\', '.$object.'}; ';
$strlistparam = empty($object) ? $prev_n : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$prev = '<span class="pagenav_prev"><a href="'.$address.$prev_n.'"'.$event.'>'.$L['pagenav_prev'].'</a></span>';
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'=0\', '.$object.'}; ';
$strlistparam = empty($object) ? 0 : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$first = '<span class="pagenav_first"><a href="'.$address.'0"'.$event.'>'.$L['pagenav_first'].'</a></span>';
}
if (($current + $perpage) < $entries)
{
$next_n = $current + $perpage;
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'='.$next_n.'\', '.$object.'}; ';
$strlistparam = empty($object) ? $next_n : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$next = '<span class="pagenav_next"><a href="'.$address.$next_n.'"'.$event.'>'.$L['pagenav_next'].'</a></span>';
$last_n = ($totalpages - 1) * $perpage;
$listparam = empty($object) ? '' : 'var list = {data: \'&'.$characters.'='.$last_n.'\', '.$object.'}; ';
$strlistparam = empty($object) ? $last_n : 'list';
$event = empty($onclick) ? '' : ' onclick="'.$listparam.'return '.$onclick.'('.$strlistparam.');"';
$last = '<span class="pagenav_last"><a href="'.$address.$last_n.'"'.$event.'>'.$L['pagenav_last'].'</a></span>';
}
$res_l = $first . $prev;
$res_r = $next . $last;
return $res_array ? array($res_l, $res_r) : $res_l . ' ' . $res_r;
}
/**
* Delete all PFS files for a specific user. Returns number of items removed.
*
* @param int $userid User ID
* @return int
*/
function sed_pfs_deleteall($userid)
{
global $db_pfs_folders, $db_pfs, $cfg;
if (!$userid)
{
return 0;
}
$sql = sed_sql_query("SELECT pfs_file, pfs_folderid FROM $db_pfs WHERE pfs_userid='$userid'");
while($row = sed_sql_fetcharray($sql))
{
$pfs_file = $row['pfs_file'];
$f = $row['pfs_folderid'];
$ff = $cfg['pfs_dir_user'].$pfs_file;
if (file_exists($ff))
{
@unlink($ff);
if(file_exists($cfg['th_dir_user'].$pfs_file))
{
@unlink($cfg['th_dir_user'].$pfs_file);
}
}
}
$sql = sed_sql_query("DELETE FROM $db_pfs_folders WHERE pff_userid='$userid'");
$num = $num + sed_sql_affectedrows();
$sql = sed_sql_query("DELETE FROM $db_pfs WHERE pfs_userid='$userid'");
$num = $num + sed_sql_affectedrows();
if ($cfg['pfsuserfolder'] && $userid>0)
{
@rmdir($cfg['pfs_dir_user']);
@rmdir($cfg['th_dir_user']);
}
return($num);
}
/**
* Returns PFS path for a user, relative from site root
*
* @param int $userid User ID
* @return string
*/
function sed_pfs_path($userid)
{
global $cfg;
if ($cfg['pfsuserfolder'])
{ return($cfg['pfs_dir'].$userid.'/'); }
else
{ return($cfg['pfs_dir']); }
}
/**
* Returns PFS path for a user, relative from PFS root
*
* @param int $userid User ID
* @return string
*/
function sed_pfs_relpath($userid)
{
global $cfg;
if ($cfg['pfsuserfolder'])
{ return($userid.'/'); }
else
{ return(''); }
}
/**
* Returns absolute path
*
* @param unknown_type $userid
* @return unknown
*/
function sed_pfs_thumbpath($userid)
{
global $cfg;
if ($cfg['pfsuserfolder'])
{ return($cfg['th_dir'].$userid.'/'); }
else
{ return($cfg['th_dir']); }
}
/**
* Reads raw data from file
*
* @param string $file File path
* @return string
*/
function sed_readraw($file)
{
return (mb_strpos($file, '..') === false && file_exists($file)) ? file_get_contents($file) : 'File not found : ' . $file;
}
/**
* Displays redirect page
*
* @param string $url Target URI
*/
function sed_redirect($url)
{
global $cfg;
if (!sed_url_check($url))
{
$url = SED_ABSOLUTE_URL . $url;
}
if ($cfg['redirmode'])
{
$output = $cfg['doctype'].<<<HTM
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset={$cfg['charset']}" />
<meta http-equiv="refresh" content="0; url=$url" />
<title>Redirecting...</title></head>
<body>Redirecting to <a href="$url">$url</a>
</body>
</html>
HTM;
header('Refresh: 0; URL='.$url);
echo $output;
exit;
}
else
{
header('Location: '.$url);
exit;
}
}
/**
* Strips all unsafe characters from file base name and converts it to latin
*
* @param string $basename File base name
* @param bool $underscore Convert spaces to underscores
* @param string $postfix Postfix appended to filename
* @return string
*/
function sed_safename($basename, $underscore = true, $postfix = '')
{
global $lang, $sed_translit;
$fname = mb_substr($basename, 0, mb_strrpos($basename, '.'));
$ext = mb_substr($basename, mb_strrpos($basename, '.') + 1);
if($lang != 'en' && is_array($sed_translit))
{
$fname = strtr($fname, $sed_translit);
}
if($underscore) $fname = str_replace(' ', '_', $fname);
$fname = preg_replace('#[^a-zA-Z0-9\-_\.\ \+]#', '', $fname);
$fname = str_replace('..', '.', $fname);
if(empty($fname)) $fname = sed_unique();
return $fname . $postfix . '.' . mb_strtolower($ext);
}
/**
* Renders a dropdown
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @param array $values Options available
* @return string
*/
function sed_selectbox($check, $name, $values)
{
$check = trim($check);
$values = explode(',', $values);
$selected = (empty($check) || $check=="00") ? "selected=\"selected\"" : '';
$result = "<select name=\"$name\" size=\"1\"><option value=\"\" $selected>---</option>";
foreach ($values as $k => $x)
{
$x = trim($x);
$selected = ($x == $check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$x\" $selected>".htmlspecialchars($x)."</option>";
}
$result .= "</select>";
return($result);
}
/**
* Renders category dropdown
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @param bool $hideprivate Hide private categories
* @return string
*/
function sed_selectbox_categories($check, $name, $hideprivate=TRUE)
{
global $db_structure, $usr, $sed_cat, $L;
$result = "<select name=\"$name\" size=\"1\">";
foreach($sed_cat as $i => $x)
{
$display = ($hideprivate) ? sed_auth('page', $i, 'W') : TRUE;
if (sed_auth('page', $i, 'R') && $i!='all' && $display)
{
$selected = ($i==$check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"".$i."\" $selected> ".$x['tpath']."</option>";
}
}
$result .= "</select>";
return($result);
}
/**
* Renders country dropdown
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @return string
*/
function sed_selectbox_countries($check,$name)
{
global $sed_countries;
$selected = (empty($check) || $check=='00') ? "selected=\"selected\"" : '';
$result = "<select name=\"$name\" size=\"1\">";
foreach($sed_countries as $i => $x)
{
$selected = ($i==$check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$i\" $selected>".$x."</option>";
}
$result .= "</select>";
return($result);
}
/**
* Generates date part dropdown
*
* @param int $utime Selected timestamp
* @param string $mode Display mode: 'short' or complete
* @param string $ext Variable name suffix
* @param int $max_year Max. year possible
* @param int $min_year Min. year possible
* @return string
*/
function sed_selectbox_date($utime, $mode, $ext='', $max_year = 2030, $min_year = 1902)
{
global $L;
list($s_year, $s_month, $s_day, $s_hour, $s_minute) = explode('-', @date('Y-m-d-H-i', $utime));
$p_monthes = array();
$p_monthes[] = array(1, $L['January']);
$p_monthes[] = array(2, $L['February']);
$p_monthes[] = array(3, $L['March']);
$p_monthes[] = array(4, $L['April']);
$p_monthes[] = array(5, $L['May']);
$p_monthes[] = array(6, $L['June']);
$p_monthes[] = array(7, $L['July']);
$p_monthes[] = array(8, $L['August']);
$p_monthes[] = array(9, $L['September']);
$p_monthes[] = array(10, $L['October']);
$p_monthes[] = array(11, $L['November']);
$p_monthes[] = array(12, $L['December']);
$result = "<select name=\"ryear".$ext."\">";
for ($i = $min_year; $i < $max_year; $i++)
{
$selected = ($i==$s_year) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$i\" $selected>$i</option>";
}
$result .= ($utime==0) ? "<option value=\"0\" selected=\"selected\">---</option>" : "<option value=\"0\">---</option>";
$result .= "</select><select name=\"rmonth".$ext."\">";
reset($p_monthes);
foreach ($p_monthes as $k => $line)
{
$selected = ($line[0]==$s_month) ? "selected=\"selected\"" : '';
$result .= "<option value=\"".$line[0]."\" $selected>".$line[1]."</option>";
}
$result .= ($utime==0) ? "<option value=\"0\" selected=\"selected\">---</option>" : "<option value=\"0\">---</option>";
$result .= "</select><select name=\"rday".$ext."\">";
for ($i = 1; $i<32; $i++)
{
$selected = ($i==$s_day) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$i\" $selected>$i</option>";
}
$result .= ($utime==0) ? "<option value=\"0\" selected=\"selected\">---</option>" : "<option value=\"0\">---</option>";
$result .= "</select> ";
if ($mode=='short')
{ return ($result); }
$result .= " <select name=\"rhour".$ext."\">";
for ($i = 0; $i<24; $i++)
{
$selected = ($i==$s_hour) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$i\" $selected>".sprintf("%02d",$i)."</option>";
}
$result .= ($utime==0) ? "<option value=\"0\" selected=\"selected\">---</option>" : "<option value=\"0\">---</option>";
$result .= "</select>:<select name=\"rminute".$ext."\">";
for ($i = 0; $i<60; $i=$i+1)
{
$selected = ($i==$s_minute) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$i\" $selected>".sprintf("%02d",$i)."</option>";
}
$result .= ($utime==0) ? "<option value=\"0\" selected=\"selected\">---</option>" : "<option value=\"0\">---</option>";
$result .= "</select>";
return ($result);
}
/**
* Renders PFS folder selection dropdown
*
* @param int $user User ID
* @param int $skip Skip folder
* @param int $check Checked folder
* @return string
*/
function sed_selectbox_folders($user, $skip, $check)
{
global $db_pfs_folders;
$sql = sed_sql_query("SELECT pff_id, pff_title, pff_isgallery, pff_ispublic FROM $db_pfs_folders WHERE pff_userid='$user' ORDER BY pff_title ASC");
$result = "<select name=\"folderid\" size=\"1\">";
if ($skip!="/" && $skip!="0")
{
$selected = (empty($check) || $check=="/") ? "selected=\"selected\"" : '';
$result .= "<option value=\"0\" $selected>/ </option>";
}
while ($row = sed_sql_fetcharray($sql))
{
if ($skip!=$row['pff_id'])
{
$selected = ($row['pff_id']==$check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"".$row['pff_id']."\" $selected>".htmlspecialchars($row['pff_title'])."</option>";
}
}
$result .= "</select>";
return ($result);
}
/**
* Returns forum category dropdown code
*
* @param int $check Selected category
* @param string $name Dropdown name
* @return string
*/
function sed_selectbox_forumcat($check, $name)
{
global $usr, $sed_forums_str, $L;
$result = "<select name=\"$name\" size=\"1\">";
if (is_array($sed_forums_str))
foreach($sed_forums_str as $i => $x)
{
$selected = ($i==$check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"".$i."\" $selected> ".$x['tpath']."</option>";
}
$result .= "</select>";
return($result);
}
/**
* Generates gender dropdown
*
* @param string $check Checked gender
* @param string $name Input name
* @return string
*/
function sed_selectbox_gender($check,$name)
{
global $L;
$genlist = array ('U', 'M', 'F');
$result = "<select name=\"$name\" size=\"1\">";
foreach(array ('U', 'M', 'F') as $i)
{
$selected = ($i==$check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"$i\" $selected>".$L['Gender_'.$i]."</option>";
}
$result .= "</select>";
return($result);
}
/**
* Returns group selection dropdown code
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @param array $skip Hidden groups
* @return string
*/
function sed_selectbox_groups($check, $name, $skip=array(0))
{
global $sed_groups;
$res = "<select name=\"$name\" size=\"1\">";
foreach($sed_groups as $k => $i)
{
$selected = ($k==$check) ? "selected=\"selected\"" : '';
$res .= (in_array($k, $skip)) ? '' : "<option value=\"$k\" $selected>".$sed_groups[$k]['title']."</option>";
}
$res .= "</select>";
return($res);
}
/**
* Returns language selection dropdown
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @return string
*/
function sed_selectbox_lang($check, $name)
{
global $sed_languages, $sed_countries, $cfg;
$handle = opendir($cfg['system_dir'].'/lang/');
while ($f = readdir($handle))
{
if ($f[0] != '.')
{ $langlist[] = $f; }
}
closedir($handle);
sort($langlist);
$result = "<select name=\"$name\" size=\"1\">";
foreach ($langlist as $i => $x)
{
$selected = ($x==$check) ? "selected=\"selected\"" : '';
$lng = (empty($sed_languages[$x])) ? $sed_countries[$x] : $sed_languages[$x];
$result .= "<option value=\"$x\" $selected>".$lng." (".$x.")</option>";
}
$result .= "</select>";
return($result);
}
/**
* Renders forum section selection dropdown
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @return string
*/
function sed_selectbox_sections($check, $name)
{
global $db_forum_sections, $cfg;
$sql = sed_sql_query("SELECT fs_id, fs_title, fs_category FROM $db_forum_sections WHERE 1 ORDER by fs_order ASC");
$result = "<select name=\"$name\" size=\"1\">";
while ($row = sed_sql_fetcharray($sql))
{
$selected = ($row['fs_id'] == $check) ? "selected=\"selected\"" : '';
$result .= "<option value=\"".$row['fs_id']."\" $selected>".htmlspecialchars(sed_cutstring($row['fs_category'], 24));
$result .= ' '.$cfg['separator'].' '.htmlspecialchars(sed_cutstring($row['fs_title'], 32));
}
$result .= "</select>";
return($result);
}
/**
* Returns skin selection dropdown
*
* @param string $check Seleced value
* @param string $name Dropdown name
* @return string
*/
function sed_selectbox_skin($check, $name)
{
$handle = opendir('skins/');
while ($f = readdir($handle))
{
if (mb_strpos($f, '.') === FALSE && is_dir('skins/' . $f))
{ $skinlist[] = $f; }
}
closedir($handle);
sort($skinlist);
$result = '<select name="'.$name.'" size="1">';
foreach($skinlist as $i => $x)
{
$selected = ($x==$check) ? 'selected="selected"' : '';
$skininfo = "skins/$x/$x.php";
if (file_exists($skininfo))
{
$info = sed_infoget($skininfo);
$result .= (!empty($info['Error'])) ? '<option value="'.$x.'" '.$selected.'>'.$x.' ('.$info['Error'].')' : '<option value="'.$x.'" '.$selected.'>'.$info['Name'];
}
else
{
$result .= '<option value="'.$x.'" $selected>'.$x;
}
$result .= '</option>';
}
$result .= '</select>';
return $result;
}
/**
* Returns skin selection dropdown
*
* @param string $skinname Skin name
* @param string $name Dropdown name
* @param string $theme Selected theme
* @return string
*/
function sed_selectbox_theme($skinname, $name, $theme)
{
global $skin_themes;
if(empty($skin_themes))
{
if(file_exists("skins/$skinname/$skinname.css"))
{
$skin_themes = array($skinname => $skinname);
}
else
{
$skin_themes = array('style' => $skinname);
}
}
$result = '<select name="'.$name.'" size="1">';
foreach($skin_themes as $x => $tname)
{
$selected = ($x==$theme) ? 'selected="selected"' : '';
$result .= '<option value="'.$x.'" '.$selected.'>'.$tname.'</option>';
}
$result .= '</select>';
return $result;
}
/**
* Gets huge user selection box
*
* @param int $to Selected user ID
* @return string
*/
function sed_selectbox_users($to)
{
global $db_users;
$result = "<select name=\"userid\">";
$sql = sed_sql_query("SELECT user_id, user_name FROM $db_users ORDER BY user_name ASC");
while ($row = sed_sql_fetcharray($sql))
{
$selected = ($row['user_id']==$to) ? "selected=\"selected\"" : '';
$result .= "<option value=\"".$row['user_id']."\" $selected>".htmlspecialchars($row['user_name'])."</option>";
}
$result .= "</select>";
return($result);
}
/**
* Sends standard HTTP headers and disables browser cache
*
* @return bool
*/
function sed_sendheaders()
{
global $cfg;
$contenttype = ($cfg['doctypeid']>2 && $cfg['xmlclient']) ? 'application/xhtml+xml' : 'text/html';
header('Expires: Fri, Apr 01 1974 00:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: post-check=0,pre-check=0', FALSE);
header('Content-Type: '.$contenttype.'; charset='.$cfg['charset']);
header('Cache-Control: no-store,no-cache,must-revalidate');
header('Cache-Control: post-check=0,pre-check=0', FALSE);
header('Pragma: no-cache');
return(TRUE);
}
/* ------------------ */
// TODO this function is obsolete, doctype should be set in header.tpl
function sed_setdoctype($type)
{
switch($type)
{
case '0': // HTML 4.01
return ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
break;
case '1': // HTML 4.01 Transitional
return ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
break;
case '2': // HTML 4.01 Frameset
return ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">");
break;
case '3': // XHTML 1.0 Strict
return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
break;
case '4': // XHTML 1.0 Transitional
return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
break;
case '5': // XHTML 1.0 Frameset
return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">");
break;
case '6': // XHTML 1.1
return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
break;
case '7': // XHTML 2 ;]
return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 2//EN\" \"http://www.w3.org/TR/xhtml2/DTD/xhtml2.dtd\">");
break;
default: // ...
return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
break;
}
}
/**
* Clears current user action in Who's online.
*
*/
function sed_shield_clearaction()
{
global $db_online, $usr;
$sql = sed_sql_query("UPDATE $db_online SET online_action='' WHERE online_ip='".$usr['ip']."'");
}
/**
* Anti-hammer protection
*
* @param int $hammer Hammer rate
* @param string $action Action type
* @param int $lastseen User last seen timestamp
* @return int
*/
function sed_shield_hammer($hammer,$action, $lastseen)
{
global $cfg, $sys, $usr;
if ($action=='Hammering')
{
sed_shield_protect();
sed_shield_clearaction();
sed_stat_inc('totalantihammer');
}
if (($sys['now']-$lastseen)<4)
{
$hammer++;
if($hammer>$cfg['shieldzhammer'])
{
sed_shield_update(180, 'Hammering');
sed_log('IP banned 3 mins, was hammering', 'sec');
$hammer = 0;
}
}
else
{
if ($hammer>0)
{ $hammer--; }
}
return($hammer);
}
/**
* Warn user of shield protection
*
*/
function sed_shield_protect()
{
global $cfg, $sys, $online_count, $shield_limit, $shield_action;
if ($cfg['shieldenabled'] && $online_count>0 && $shield_limit>$sys['now'])
{
sed_diefatal('Shield protection activated, please retry in '.($shield_limit-$sys['now']).' seconds...<br />After this duration, you can refresh the current page to continue.<br />Last action was : '.$shield_action);
}
}
/**
* Updates shield state
*
* @param int $shield_add Hammer
* @param string $shield_newaction New action type
*/
function sed_shield_update($shield_add, $shield_newaction)
{
global $cfg, $usr, $sys, $db_online;
if ($cfg['shieldenabled'])
{
$shield_newlimit = $sys['now'] + floor($shield_add * $cfg['shieldtadjust'] /100);
$sql = sed_sql_query("UPDATE $db_online SET online_shield='$shield_newlimit', online_action='$shield_newaction' WHERE online_ip='".$usr['ip']."'");
}
}
/**
* Returns skin file path
*
* @param mixed $base Item name (string), or base names (array)
* @return string
*/
function sed_skinfile($base, $plug = false, $admn = false)
{
global $usr, $cfg;
if (is_string($base) && mb_strpos($base, '.') !== false)
{
$base = explode('.', $base);
}
$bname = is_array($base) ? $base[0] : $base;
if($admn)
{
$scan_prefix[] = './skins/'.$usr['skin'].'/admin/';
if ($usr['skin'] != $cfg['defaultskin'])
{
$scan_prefix[] = './skins/'.$cfg['defaultskin'].'/admin/';
}
if ($plug)
{
$scan_prefix[] = $cfg['plugins_dir'].'/'.$bname.'/tpl/admin/';
}
}
elseif($plug)
{
$scan_prefix[] = './skins/'.$usr['skin'].'/plugins/';
$scan_prefix[] = './skins/'.$usr['skin'].'/plugin.standalone.';
if ($usr['skin'] != $cfg['defaultskin'])
{
$scan_prefix[] = './skins/'.$cfg['defaultskin'].'/plugins/';
$scan_prefix[] = './skins/'.$cfg['defaultskin'].'/plugin.standalone.';
}
$scan_prefix[] = $cfg['plugins_dir'].'/'.$bname.'/tpl/';
$scan_prefix[] = $cfg['plugins_dir'].'/'.$bname .'/';
}
$scan_prefix[] = 'skins/'.$usr['skin'].'/';
if ($usr['skin'] != $cfg['defaultskin'])
{
$scan_prefix[] = 'skins/'.$cfg['defaultskin'].'/';
}
if (is_array($base))
{
$base_depth = count($base);
for ($i = $base_depth; $i > 0; $i--)
{
$levels = array_slice($base, 0, $i);
$skinfile = implode('.', $levels).'.tpl';
foreach ($scan_prefix as $pfx)
{
if (file_exists($pfx . $skinfile))
{
return $pfx . $skinfile;
}
}
}
}
else
{
foreach ($scan_prefix as $pfx)
{
if (file_exists($pfx . $base . '.tpl'))
{
return $pfx . $base . '.tpl';
}
}
}
//$skinfile = is_array($base) ? implode('.', $base) . '.tpl' : $base . '.tpl';
//throw new Exception("Template file <em>$skinfile</em> was not found. Please check your skin!");
return '';
}
/**
* Parses smiles in text
*
* @param string $res Source text
* @return string
*/
function sed_smilies($res)
{
global $sed_smilies;
if (is_array($sed_smilies))
{
foreach($sed_smilies as $k => $v)
{ $res = str_replace($v['smilie_code'],"<img src=\"".$v['smilie_image']."\" alt=\"\" />", $res); }
}
return($res);
}
/**
* Gets XSS protection code
*
* @return string
*/
function sed_sourcekey()
{
global $sys;
return $sys['xk'];
}
/*
* ===================================== Statistics API ==========================================
*/
/**
* Creates new stats parameter
*
* @param string $name Parameter name
*/
function sed_stat_create($name)
{
global $db_stats;
sed_sql_query("INSERT INTO $db_stats (stat_name, stat_value) VALUES ('".sed_sql_prep($name)."', 1)");
}
/**
* Returns statistics parameter
*
* @param string $name Parameter name
* @return int
*/
function sed_stat_get($name)
{
global $db_stats;
$sql = sed_sql_query("SELECT stat_value FROM $db_stats where stat_name='$name' LIMIT 1");
return (sed_sql_numrows($sql) > 0) ? (int) sed_sql_result($sql, 0, 'stat_value') : FALSE;
}
/**
* Increments stats
*
* @param string $name Parameter name
*/
function sed_stat_inc($name)
{
global $db_stats;
sed_sql_query("UPDATE $db_stats SET stat_value=stat_value+1 WHERE stat_name='$name'");
}
/**
* Inserts new stat or increments value if it already exists
*
* @param string $name Parameter name
*/
function sed_stat_update($name)
{
global $db_stats;
sed_sql_query("INSERT INTO $db_stats (stat_name, stat_value)
VALUES ('".sed_sql_prep($name)."', 1)
ON DUPLICATE KEY UPDATE stat_value=stat_value+1");
}
/*
* =========================================================================================
*/
/**
* Returns substring position in file
*
* @param string $file File path
* @param string $str Needle
* @param int $maxsize Search limit
* @return int
*/
function sed_stringinfile($file, $str, $maxsize=32768)
{
if ($fp = @fopen($file, 'r'))
{
$data = fread($fp, $maxsize);
$pos = mb_strpos($data, $str);
$result = !($pos===FALSE);
}
else
{ $result = FALSE; }
@fclose($fp);
return ($result);
}
/*
* ===================================== Tags API ==========================================
*/
/**
* Tags a given item from a specific area with a keyword
*
* @param string $tag The tag (keyword)
* @param int $item Item ID
* @param string $area Site area code (e.g. 'pages', 'forums', 'blog')
* @return bool
*/
function sed_tag($tag, $item, $area = 'pages')
{
global $db_tag_references;
$item = (int) $item;
if(sed_tag_isset($tag, $item, $area))
{
return false;
}
sed_sql_query("INSERT INTO $db_tag_references VALUES('".sed_sql_prep($tag)."', $item, '$area')");
sed_tag_register($tag);
return true;
}
/**
* Collects data for a tag cloud in some area. The result is an associative array with
* tags as keys and count of entries as values.
*
* @param string $area Site area
* @param string $order Should be 'tag' to order the result set by tag (alphabetical) or 'cnt' to order it by item count (descending)
* @param int $limit Use this parameter to limit number of rows in the result set
* @return array
*/
function sed_tag_cloud($area = 'all', $order = 'tag', $limit = null)
{
global $db_tag_references;
$res = array();
$limit = is_null($limit) ? '' : ' LIMIT ' . $limit;
switch($order)
{
case 'Alphabetical':
$order = '`tag`';
break;
case 'Frequency':
$order = '`cnt` DESC';
break;
default:
$order = 'RAND()';
}
$where = $area == 'all' ? '' : "WHERE tag_area = '$area'";
$sql = sed_sql_query("SELECT `tag`, COUNT(*) AS `cnt`
FROM $db_tag_references
$where
GROUP BY `tag`
ORDER BY $order $limit");
while($row = sed_sql_fetchassoc($sql))
{
$res[$row['tag']] = $row['cnt'];
}
sed_sql_freeresult($sql);
return $res;
}
/**
* Gets an array of autocomplete options for a given tag
*
* @param string $tag Beginning of a tag
* @param int $min_length Minimal length of the beginning
* @return array
*/
function sed_tag_complete($tag, $min_length = 3)
{
global $db_tags;
if(mb_strlen($tag) < $min_length)
{
return false;
}
$res = array();
$sql = sed_sql_query("SELECT `tag` FROM $db_tags WHERE `tag` LIKE '".sed_sql_prep($tag)."%'");
while($row = sed_sql_fetchassoc($sql))
{
$res[] = $row['tag'];
}
sed_sql_freeresult($sql);
return $res;
}
/**
* Returns number of items tagged with a specific keyword
*
* @param string $tag The tag (keyword)
* @param string $area Site area or empty to count in all areas
* @return int
*/
function sed_tag_count($tag, $area = '')
{
global $db_tag_references;
$query = "SELECT COUNT(*) FROM $db_tag_references WHERE `tag` = '".sed_sql_prep($tag)."'";
if(!empty($area))
{
$query .= " AND tag_area = '$area'";
}
return (int) sed_sql_result(sed_sql_query($query), 0, 0);
}
/**
* Checks whether the tag has already been registered in the dictionary
*
* @param string $tag The tag
* @return bool
*/
function sed_tag_exists($tag)
{
global $db_tags;
return sed_sql_result(sed_sql_query("SELECT COUNT(*) FROM $db_tags WHERE `tag` = '".sed_sql_prep($tag)."'"), 0, 0) == 1;
}
/**
* Checks whether a tag has been already set on a specific item
*
* @param string $tag The tag (keyword)
* @param int $item Item ID
* @param string $area Site area code (e.g. 'pages', 'forums', 'blog')
* @return bool
*/
function sed_tag_isset($tag, $item, $area = 'pages')
{
global $db_tag_references;
$item = (int) $item;
$sql = sed_sql_query("SELECT COUNT(*) FROM $db_tag_references WHERE `tag` = '".sed_sql_prep($tag)."' AND tag_item = $item AND tag_area = '$area'");
return sed_sql_result($sql, 0, 0) == 1;
}
/**
* Returns an array containing tags which have been set on an item
*
* @param int $item Item ID
* @param string $area Site area code (e.g. 'pages', 'forums', 'blog')
* @return array
*/
function sed_tag_list($item, $area = 'pages')
{
global $db_tag_references;
$res = array();
$sql = sed_sql_query("SELECT `tag` FROM $db_tag_references WHERE tag_item = $item AND tag_area = '$area'");
while($row = sed_sql_fetchassoc($sql))
{
$res[] = $row['tag'];
}
sed_sql_freeresult($sql);
return $res;
}
/**
* Parses user input into array of valid and safe tags
*
* @param string $input Comma separated user input
* @return array
*/
function sed_tag_parse($input)
{
$res = array();
$tags = explode(',', $input);
foreach($tags as $tag)
{
$tag = sed_tag_prep($tag);
if(!empty($tag))
{
$res[] = $tag;
}
}
$res = array_unique($res);
return $res;
}
/**
* Convert the tag to lowercase and prepare it for SQL operations. Please call this after sed_import()!
*
* @param string $tag The tag
* @return string
*/
function sed_tag_prep($tag)
{
static $invalid = array('`', '^', ':', '?', '=', '|', '\\', '/', '"', "\t", "\r\n", "\n");
$tag = str_replace($invalid, ' ', $tag);
$tag = preg_replace('#\s\s+#', ' ', $tag);
$tag = trim($tag);
return mb_strtolower($tag);
}
/**
* Attempts to register a tag in the dictionary. Duplicate entries are just ignored.
*
* @param string $tag The tag
*/
function sed_tag_register($tag)
{
global $db_tags;
sed_sql_query("INSERT IGNORE INTO $db_tags VALUES('".sed_sql_prep($tag)."')");
}
/**
* Removes tag reference from a specific item
*
* @param string $tag The tag (keyword)
* @param int $item Item ID
* @param string $area Site area code (e.g. 'pages', 'forums', 'blog')
* @return bool
*/
function sed_tag_remove($tag, $item, $area = 'pages')
{
global $db_tag_references;
if(sed_tag_isset($tag, $item, $area))
{
sed_sql_query("DELETE FROM $db_tag_references WHERE `tag` = '".sed_sql_prep($tag)."' AND tag_item = $item AND tag_area = '$area'");
return true;
}
return false;
}
/**
* Removes all tags attached to an item, or all tags from area if item is set to 0.
* Returns number of tag references affected.
*
* @param int $item Item ID
* @param string $area Site area
* @return int
*/
function sed_tag_remove_all($item = 0, $area = 'pages')
{
global $db_tag_references;
if($item == 0)
{
sed_sql_query("DELETE FROM $db_tag_references WHERE tag_area = '$area'");
}
else
{
sed_sql_query("DELETE FROM $db_tag_references WHERE tag_item = $item AND tag_area = '$area'");
}
return sed_sql_affectedrows();
}
/**
* Converts a lowercase tag into title-case string (capitalizes first latters of the words)
*
* @param string $tag A tag
* @return string
*/
function sed_tag_title($tag)
{
return mb_convert_case($tag, MB_CASE_TITLE);
}
/**
* Unregisters a tag from the dictionary
*
* @param string $tag The tag
*/
function sed_tag_unregister($tag)
{
global $db_tags;
sed_sql_query("DELETE FROM $db_tags WHERE `tag` = '".sed_sql_prep($tag)."'");
}
/*
* ==========================================================================================
*/
/**
* Tries to detect and fetch a user theme or returns FALSE on error.
*
* @global array $usr User object
* @global array $cfg Configuration
* @global array $out Output vars
* @return mixed
*/
function sed_themefile()
{
global $usr, $cfg, $out;
if(file_exists('skins/'.$usr['skin'].'/'.$usr['theme'].'.css'))
{
return 'skins/'.$usr['skin'].'/'.$usr['theme'].'.css';
}
elseif(file_exists('skins/'.$usr['skin'].'/css/'))
{
if(file_exists('skins/'.$usr['skin'].'/css/'.$usr['theme'].'.css'))
{
return 'skins/'.$usr['skin'].'/css/'.$usr['theme'].'.css';
}
elseif(file_exists('skins/'.$usr['skin'].'/css/'.$cfg['defaulttheme'].'.css'))
{
$out['notices'] .= $L['com_themefail'];
$usr['theme'] = $cfg['defaulttheme'];
return 'skins/'.$usr['skin'].'/css/'.$cfg['defaulttheme'].'.css';
}
}
elseif(file_exists('skins/'.$usr['skin']))
{
if(file_exists('skins/'.$usr['skin'].'/'.$cfg['defaulttheme'].'.css'))
{
$out['notices'] .= $L['com_themefail'];
$usr['theme'] = $cfg['defaulttheme'];
return 'skins/'.$usr['skin'].'/'.$cfg['defaulttheme'].'.css';
}
elseif(file_exists('skins/'.$usr['skin'].'/'.$usr['skin'].'.css'))
{
$out['notices'] .= $L['com_themefail'];
$usr['theme'] = $usr['skin'];
return 'skins/'.$usr['skin'].'/'.$usr['skin'].'.css';
}
elseif(file_exists('skins/'.$usr['skin'].'/style.css'))
{
$out['notices'] .= $L['com_themefail'];
$usr['theme'] = 'style';
return 'skins/'.$usr['skin'].'/style.css';
}
}
$out['notices'] .= $L['com_themefail'];
if(file_exists('skins/'.$cfg['defaultskin'].'/'.$cfg['defaulttheme'].'.css'))
{
$usr['skin'] = $cfg['defaultskin'];
$usr['theme'] = $cfg['defaulttheme'];
return 'skins/'.$cfg['defaultskin'].'/'.$cfg['defaulttheme'].'.css';
}
elseif(file_exists('skins/'.$cfg['defaultskin'].'/css/'.$cfg['defaulttheme'].'.css'))
{
$usr['skin'] = $cfg['defaultskin'];
$usr['theme'] = $cfg['defaulttheme'];
return 'skins/'.$cfg['defaultskin'].'/css/'.$cfg['defaulttheme'].'.css';
}
else
{
return false;
}
}
/**
* Returns a String afterbeing processed by a sprintf mask for titles
*
* @param string $area Area maskname or actual mask
* @param array $tags Tag Masks
* @param array $data title options
* @return string
*/
function sed_title($mask, $tags, $data)
{
global $cfg;
$mask = (!empty($cfg[$mask])) ? $cfg[$mask] : $mask;
$mask = str_replace($tags[0], $tags[1], $mask);
$cnt = count($data);
for ($i = 0; $i < $cnt; $i++)
{
if (version_compare(PHP_VERSION, '5.2.2', '<='))
{
$data[$i] = htmlspecialchars($data[$i], ENT_COMPAT, 'UTF-8');
}
else
{
$data[$i] = htmlspecialchars($data[$i], ENT_COMPAT, 'UTF-8', false);
}
}
$title = vsprintf($mask, $data);
return $title;
}
/**
* Sends item to trash
*
* @param string $type Item type
* @param string $title Title
* @param int $itemid Item ID
* @param mixed $datas Item contents
*/
function sed_trash_put($type, $title, $itemid, $datas)
{
global $db_trash, $sys, $usr;
$sql = sed_sql_query("INSERT INTO $db_trash (tr_date, tr_type, tr_title, tr_itemid, tr_trashedby, tr_datas)
VALUES
(".$sys['now_offset'].", '".sed_sql_prep($type)."', '".sed_sql_prep($title)."', '".sed_sql_prep($itemid)."', ".$usr['id'].", '".sed_sql_prep(serialize($datas))."')");
}
/**
* Generates random string
*
* @param int $l Length
* @return string
*/
function sed_unique($l=16)
{
return(mb_substr(md5(mt_rand()), 0, $l));
}
/**
* Loads URL Transformation Rules
*
*/
function sed_load_urltrans()
{
global $sed_urltrans;
$sed_urltrans = array();
$fp = fopen('./datas/urltrans.dat', 'r');
// Rules
while($line = trim(fgets($fp), " \t\r\n"))
{
$parts = explode("\t", $line);
$rule = array();
$rule['trans'] = $parts[2];
$parts[1] == '*' ? $rule['params'] = array() : mb_parse_str($parts[1], $rule['params']);
foreach($rule['params'] as $key => $val)
{
if (mb_strpos($val, '|') !== false)
{
$rule['params'][$key] = explode('|', $val);
}
}
$sed_urltrans[$parts[0]][] = $rule;
}
fclose($fp);
}
/**
* Splits a query string into keys and values array. In comparison with built-in
* parse_str() function, this doesn't apply addslashes and urldecode to parameters
* and does not support arrays and complex parameters.
*
* @param string $str Query string
* @return array
*/
function sed_parse_str($str)
{
$res = array();
foreach (explode('&', $str) as $item)
{
if (!empty($item))
{
list($key, $val) = explode('=', $item);
$res[$key] = $val;
}
}
return $res;
}
/**
* Transforms parameters into URL by following user-defined rules
*
* @param string $name Site area or script name
* @param mixed $params URL parameters as array or parameter string
* @param string $tail URL postfix, e.g. anchor
* @param bool $header Set this TRUE if the url will be used in HTTP header rather than body output
* @return string
*/
function sed_url($name, $params = '', $tail = '', $header = false)
{
global $cfg, $sed_urltrans;
// Preprocess arguments
$args = is_array($params) ? $params : sed_parse_str($params);
$area = empty($sed_urltrans[$name]) ? '*' : $name;
// Find first matching rule
$url = $sed_urltrans['*'][0]['trans']; // default rule
$rule = array();
if(!empty($sed_urltrans[$area]))
{
foreach($sed_urltrans[$area] as $rule)
{
$matched = true;
foreach($rule['params'] as $key => $val)
{
if(empty($args[$key])
|| (is_array($val) && !in_array($args[$key], $val))
|| ($val != '*' && $args[$key] != $val))
{
$matched = false;
break;
}
}
if($matched)
{
$url = $rule['trans'];
break;
}
}
}
// Some special substitutions
$mainurl = parse_url($cfg['mainurl']);
$spec['_area'] = $name;
$spec['_host'] = $mainurl['host'];
$spec['_rhost'] = $_SERVER['HTTP_HOST'];
$spec['_path'] = SED_SITE_URI;
// Transform the data into URL
if(preg_match_all('#\{(.+?)\}#', $url, $matches, PREG_SET_ORDER))
{
foreach($matches as $m)
{
if($p = mb_strpos($m[1], '('))
{
// Callback
$func = mb_substr($m[1], 0, $p);
$url = str_replace($m[0], $func($args, $spec), $url);
}
elseif(mb_strpos($m[1], '!$') === 0)
{
// Unset
$var = mb_substr($m[1], 2);
$url = str_replace($m[0], '', $url);
unset($args[$var]);
}
else
{
// Substitute
$var = mb_substr($m[1], 1);
if(isset($spec[$var]))
{
$url = str_replace($m[0], urlencode($spec[$var]), $url);
}
elseif(isset($args[$var]))
{
$url = str_replace($m[0], urlencode($args[$var]), $url);
unset($args[$var]);
}
else
{
$url = str_replace($m[0], urlencode($GLOBALS[$var]), $url);
}
}
}
}
// Append query string if needed
if(!empty($args))
{
$qs = '?';
$sep = $header ? '&' : '&';
$sep_len = mb_strlen($sep);
foreach($args as $key => $val)
{
// Exclude static parameters that are not used in format,
// they should be passed by rewrite rule (htaccess)
if($rule['params'][$key] != $val)
{
$qs .= $key .'=' . urlencode($val) . $sep;
}
}
$qs = mb_substr($qs, 0, -$sep_len);
$url .= $qs;
}
// Almost done
$url .= $tail;
$url = str_replace('&amp;', '&', $url);
return $url;
}
/**
* Checks if an absolute URL belongs to current site or its subdomains
*
* @param string $url Absolute URL
* @return bool
*/
function sed_url_check($url)
{
global $sys;
return preg_match('`^'.preg_quote($sys['scheme'].'://').'([^/]+\.)?'.preg_quote($sys['domain']).'`i', $url);
}
/**
* Encodes a string for use in URLs
*
* @param string $str Source string
* @param bool $translit Transliterate non-English characters
* @return string
*/
function sed_urlencode($str, $translit = false)
{
global $lang, $sed_translit;
if($translit && $lang != 'en' && is_array($sed_translit))
{
// Apply transliteration
$str = strtr($str, $sed_translit);
}
return $str;
}
/**
* Decodes a string that has been previously encoded with sed_urlencode()
*
* @param string $str Encoded string
* @param bool $translit Transliteration of non-English characters was used
* @return string
*/
function sed_urldecode($str, $translit = false)
{
global $lang, $sed_translitb;
if($translit && $lang != 'en' && is_array($sed_translitb))
{
// Apply transliteration
$str = strtr($str, $sed_translitb);
}
return $str;
}
/**
* Store URI-redir to session
*
* @global $sys
*/
function sed_uriredir_store()
{
global $sys;
if ($_SERVER['REQUEST_METHOD'] != 'POST' // not form action/POST
&& empty($_GET['x']) // not xg, hence not form action/GET and not command from GET
&& !defined('SED_MESSAGE') // not message location
&& (!defined('SED_USERS') // not login/logout location
|| empty($_GET['m'])
|| !in_array($_GET['m'], array('auth', 'logout', 'register'))
)
)
{
$_SESSION['s_uri_redir'] = $sys['uri_redir'];
}
}
/**
* Apply URI-redir that stored in session
*
* @param bool $cfg_redir Configuration of redirect back
* @global $redirect
*/
function sed_uriredir_apply($cfg_redir = true)
{
global $redirect;
if ($cfg_redir && empty($redirect) && !empty($_SESSION['s_uri_redir']))
{
$redirect = $_SESSION['s_uri_redir'];
}
}
/**
* Checks URI-redir for xg before redirect
*
* @param string $uri Target URI
*/
function sed_uriredir_redirect($uri)
{
if (mb_strpos($uri, '&x=') !== false || mb_strpos($uri, '?x=') !== false)
{
$uri = sed_url('index'); // xg, not redirect to form action/GET or to command from GET
}
sed_redirect($uri);
}
/**
* Fetches user entry from DB
*
* @param int $id User ID
* @return array
*/
function sed_userinfo($id)
{
global $db_users;
$sql = sed_sql_query("SELECT * FROM $db_users WHERE user_id='$id'");
if ($res = sed_sql_fetcharray($sql))
{ return ($res); }
else
{
$res['user_name'] = '?';
return ($res);
}
}
/**
* Checks whether user is online
*
* @param int $id User ID
* @return bool
*/
function sed_userisonline($id)
{
global $sed_usersonline;
$res = FALSE;
if (is_array($sed_usersonline))
{ $res = (in_array($id,$sed_usersonline)) ? TRUE : FALSE; }
return ($res);
}
/**
* Wraps text
*
* @param string $str Source text
* @param int $wrap Wrapping boundary
* @return string
*/
function sed_wraptext($str,$wrap=128)
{
if (!empty($str))
{ $str = preg_replace("/([^\n\r ?&\.\/<>\"\\-]{80})/i"," \\1\n", $str); }
return($str);
}
/**
* Returns XSS protection variable for GET URLs
*
* @return unknown
*/
function sed_xg()
{
global $sys;
return ('x='.$sys['xk']);
}
/**
* Returns XSS protection field for POST forms
*
* @return string
*/
function sed_xp()
{
global $sys;
return '<div style="display:inline;margin:0;padding:0"><input type="hidden" name="x" value="'.$sys['xk'].'" /></div>';
}
/**
* Set cookie with optional HttpOnly flag
* @param string $name The name of the cookie
* @param string $value The value of the cookie
* @param int $expire The time the cookie expires in unixtime
* @param string $path The path on the server in which the cookie will be available on.
* @param string $domain The domain that the cookie is available.
* @param bool $secure Indicates that the cookie should only be transmitted over a secure HTTPS connection. When set to TRUE, the cookie will only be set if a secure connection exists.
* @param bool $httponly HttpOnly flag
* @return bool
*/
function sed_setcookie($name, $value, $expire, $path, $domain, $secure = false, $httponly = false)
{
if (mb_strpos($domain, '.') === FALSE)
{
// Some browsers don't support cookies for local domains
$domain = '';
}
if ($domain != '')
{
// Make sure www. is stripped and leading dot is added for subdomain support on some browsers
if (mb_strtolower(mb_substr($domain, 0, 4)) == 'www.')
{
$domain = mb_substr($domain, 4);
}
if ($domain[0] != '.')
{
$domain = '.' . $domain;
}
}
if (version_compare(PHP_VERSION, '5.2.0', '>='))
{
return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}
if (!$httponly)
{
return setcookie($name, $value, $expire, $path, $domain, $secure);
}
if (trim($domain) != '')
{
$domain .= ($secure ? '; secure' : '') . ($httponly ? '; httponly' : '');
}
return setcookie($name, $value, $expire, $path, $domain);
}
/* ============== FLAGS AND COUNTRIES (ISO 3166) =============== */
$sed_languages['de']= 'Deutsch';
$sed_languages['dk']= 'Dansk';
$sed_languages['es']= 'Espa�ol';
$sed_languages['fi']= 'Suomi';
$sed_languages['fr']= 'Fran�ais';
$sed_languages['it']= 'Italiano';
$sed_languages['nl']= 'Nederlands';
$sed_languages['ru']= 'Русский';
$sed_languages['se']= 'Svenska';
$sed_languages['en']= 'English';
$sed_languages['pl']= 'Polski';
$sed_languages['pt']= 'Portugese';
$sed_languages['cn']= '汉语';
$sed_languages['gr']= 'Greek';
$sed_languages['hu']= 'Hungarian';
$sed_languages['jp']= '日本語';
$sed_languages['kr']= '한국말';
// XTemplate classes
require_once $cfg['system_dir'].'/cotemplate.php';
// =========== Extra fields for pages =====================
/**
* Add extra field for pages
*
* @param string $sql_table Table for adding extrafield (without sed_)
* @param string $name Field name (unique)
* @param string $type Field type (input, textarea etc)
* @param string $html HTML display of element without parameter "name="
* @param string $variants Variants of values (for radiobuttons, selectors etc)
* @param string $description Description of field (optional, for admin)
* @param bool $noalter Do not ALTER the table, just register the extra field
* @return bool
*
*/
function sed_extrafield_add($sql_table, $name, $type, $html, $variants="", $description="", $noalter = FALSE)
{
global $db_extra_fields, $db_x;
$fieldsres = sed_sql_query("SELECT field_name FROM $db_extra_fields WHERE field_location='$sql_table'");
while($row = sed_sql_fetchassoc($fieldsres))
{
$extrafieldsnames[] = $row['field_name'];
}
if(count($extrafieldsnames)>0) if (in_array($name,$extrafieldsnames)) return 0; // No adding - fields already exist
// Check table sed_$sql_table - if field with same name exists - exit.
if (sed_sql_numrows(sed_sql_query("SHOW COLUMNS FROM $db_x$sql_table LIKE '%\_$name'")) > 0 && !$noalter)
{
return FALSE;
}
$fieldsres = sed_sql_query("SELECT * FROM $db_x$sql_table LIMIT 1");
while ($i < mysql_num_fields($fieldsres))
{
$column = mysql_fetch_field($fieldsres, $i);
// get column prefix in this table
$column_prefix = substr($column->name, 0, strpos($column->name, "_"));
preg_match("#.*?_$name$#",$column->name,$match);
if($match[1]!="" && !$noalter) return false; // No adding - fields already exist
$i++;
}
$extf['location'] = $sql_table;
$extf['name'] = $name;
$extf['type'] = $type;
$extf['html'] = $html;
$extf['variants'] = $variants;
$extf['description'] = $description;
$step1 = sed_sql_insert($db_extra_fields, $extf, 'field_') == 1;
if ($noalter)
{
return $step1;
}
switch($type)
{
case "input": $sqltype = "VARCHAR(255)"; break;
case "textarea": $sqltype = "TEXT"; break;
case "select": $sqltype = "VARCHAR(255)"; break;
case "checkbox": $sqltype = "BOOL"; break;
case "radio": $sqltype = "VARCHAR(255)"; break;
}
$sql = "ALTER TABLE $db_x$sql_table ADD ".$column_prefix."_$name $sqltype ";
$step2 = sed_sql_query($sql);
return $step1&&$step2;
}
/**
* Update extra field for pages
*
* @param string $sql_table Table contains extrafield (without sed_)
* @param string $oldname Exist name of field
* @param string $name Field name (unique)
* @param string $type Field type (input, textarea etc)
* @param string $html HTML display of element without parameter "name="
* @param string $variants Variants of values (for radiobuttons, selectors etc)
* @param string $description Description of field (optional, for admin)
* @return bool
*
*/
function sed_extrafield_update($sql_table, $oldname, $name, $type, $html, $variants="", $description="")
{
global $db_extra_fields, $db_x;
$fieldsres = sed_sql_query("SELECT COUNT(*) FROM $db_extra_fields
WHERE field_name = '$oldname' AND field_location='$sql_table'");
if (sed_sql_numrows($fieldsres) <= 0
|| $name != $oldname
&& sed_sql_numrows(sed_sql_query("SHOW COLUMNS FROM $db_x$sql_table LIKE '%\_$name'")) > 0)
{
// Attempt to edit non-extra field or override an existing field
return FALSE;
}
$field = sed_sql_fetchassoc($fieldsres);
$fieldsres = sed_sql_query("SELECT * FROM $db_x$sql_table LIMIT 1");
$column = mysql_fetch_field($fieldsres, 0);
$column_prefix = substr($column->name, 0, strpos($column->name, "_"));
$alter = FALSE;
if ($name != $field['field_name'])
{
$extf['name'] = $name;
$alter = TRUE;
}
if ($type != $field['field_type'])
{
$extf['type'] = $type;
$alter = TRUE;
}
if ($html != $field['field_html'])
$extf['html'] = $html;
if ($variants != $field['field_variants'])
$extf['variants'] = $variants;
if ($description != $field['field_description'])
$extf['description'] = $description;
$step1 = sed_sql_update($db_extra_fields, "field_name = '$oldname' AND field_location='$sql_table'", $extf, 'field_') == 1;
if (!$alter) return $step1;
switch ($type)
{
case "input": $sqltype = "VARCHAR(255)"; break;
case "textarea": $sqltype = "TEXT"; break;
case "select": $sqltype = "VARCHAR(255)"; break;
case "checkbox": $sqltype = "BOOL"; break;
case "radio": $sqltype = "VARCHAR(255)"; break;
}
$sql = "ALTER TABLE $db_x$sql_table CHANGE ".$column_prefix."_$oldname ".$column_prefix."_$name $sqltype ";
$step2 = sed_sql_query($sql);
return $step1&&$step2;
}
/**
* Delete extra field
*
* @param string $sql_table Table contains extrafield (without sed_)
* @param string $name Name of extra field
* @return bool
*
*/
function sed_extrafield_remove($sql_table, $name)
{
global $db_extra_fields, $db_x;
if ((int) sed_sql_result(sed_sql_query("SELECT COUNT(*) FROM $db_extra_fields
WHERE field_name = '$name' AND field_location='$sql_table'"), 0, 0) <= 0)
{
// Attempt to remove non-extra field
return FALSE;
}
$fieldsres = sed_sql_query("SELECT * FROM $db_x$sql_table LIMIT 1");
$column = mysql_fetch_field($fieldsres, 0);
$column_prefix = substr($column->name, 0, strpos($column->name, "_"));
$step1 = sed_sql_delete($db_extra_fields, "field_name = '$name' AND field_location='$sql_table'") == 1;
$sql = "ALTER TABLE $db_x$sql_table DROP ".$column_prefix."_".$name;
$step2 = sed_sql_query($sql);
return $step1&&$step2;
}
/**
* Makes correct plural forms of words
*
* @global string $lang Current language
* @param int $digit Numeric value
* @param string $expr Word or expression
* @param bool $onlyword Return only words, without numbers
* @param bool $canfrac - Numeric value can be Decimal Fraction
* @return string
*/
function sed_declension($digit, $expr, $onlyword = false, $canfrac = false)
{
if (!is_array($expr))
{
return trim(($onlyword ? '' : "$digit ") . $expr);
}
global $lang;
if ($canfrac)
{
$is_frac = floor($digit) != $digit;
$i = $digit;
}
else
{
$is_frac = false;
$i = preg_replace('#\D+#', '', $digit);
}
$plural = sed_get_plural($i, $lang, $is_frac);
$cnt = count($expr);
return trim(($onlyword ? '' : "$digit ") . (($cnt > 0 && $plural < $cnt) ? $expr[$plural] : ''));
}
/**
* Used in sed_declension to get rules for concrete languages
*
* @param int $plural Numeric value
* @param string $lang Target language code
* @param bool $is_frac true if numeric value is fraction, otherwise false
* @return int
*/
function sed_get_plural($plural, $lang, $is_frac = false)
{
switch ($lang)
{
case 'en':
case 'de':
case 'nl':
case 'se':
case 'us':
return ($plural == 1) ? 1 : 0;
case 'fr':
return ($plural > 1) ? 0 : 1;
case 'ru':
case 'ua':
if ($is_frac)
{
return 1;
}
$plural %= 100;
return (5 <= $plural && $plural <= 20) ? 2 : ((1 == ($plural %= 10)) ? 0 : ((2 <= $plural && $plural <= 4) ? 1 : 2));
default:
return 0;
}
}
/*
* ================================ Debugging Facilities ================================
*/
/**
* Accepts several variables and prints their values in debug mode (var dump).
*
* @example sed_assert($foo, $bar);
* @see sed_watch(), sed_backtrace(), sed_vardump()
*/
function sed_print()
{
ob_end_clean();
$vars = func_get_args();
foreach ($vars as $name => $var)
{
var_dump($var);
}
die();
}
/**
* Dumps current state of its arguments to debug log file and continues normal script execution.
*
* @example sed_watch($foo, $bar);
* @see sed_assert(), sed_checkpoint(), SED_DEBUG_LOGFILE
*/
function sed_watch()
{
$fp = fopen(SED_DEBUG_LOGFILE, 'a');
$btrace = debug_backtrace();
fputs($fp, $btrace[1]['file'] . ', ' . $btrace[1]['line'] . ":\n");
$vars = func_get_args();
foreach ($vars as $name => $var)
{
fputs($fp, "arg #$name = " .print_r($var, TRUE) ."\n");
}
fputs($fp, "----------------\n");
fclose($fp);
}
/**
* Prints program execution backtrace.
*
* @param bool $clear_screen If TRUE displays backtrace only. Otherwise it will be printed in normal flow.
* @see sed_assert(), sed_vardump()
*/
function sed_backtrace($clear_screen = TRUE)
{
if ($clear_screen)
{
ob_end_clean();
}
debug_print_backtrace();
if ($clear_screen)
{
die();
}
}
/**
* Prints structure and contents of all global variables currently assigned.
*
* @param bool $clear_screen If TRUE displays vardump only. Otherwise it will be printed in normal flow.
* @see SED_VARDUMP_LOCALS, sed_assert(), sed_backtrace()
*/
function sed_vardump($clear_screen = TRUE)
{
if ($clear_screen)
{
ob_end_clean();
}
foreach ($GLOBALS as $key => $val)
{
if ($key != 'GLOBALS')
{
echo "<br /><em>$key</em><br />";
var_dump($val);
}
}
if ($clear_screen)
{
die();
}
}
/**
* Local vardump macro. Prints structure and contents of all variables in the local scope.
*
* @example eval(SED_VARDUMP_LOCALS);
* @see sed_vardump(), sed_watch()
*/
define('SED_VARDUMP_LOCALS', 'ob_end_clean();
$debug_vars = get_defined_vars();
foreach ($debug_vars as $debug_key => $debug_val)
{
if ($debug_key != "GLOBALS" && $debug_key != "debug_vars")
{
echo "<br /><em>$debug_key</em><br />";
var_dump($debug_val);
}
}
die();');
/**
* Dumps current state of global variables into debug log file and continues normal script execution.
*
* @see SED_CHECKPOINT_LOCALS, SED_DEBUG_LOGFILE, sed_watch(), sed_vardump()
*/
function sed_checkpoint()
{
$fp = fopen(SED_DEBUG_LOGFILE, 'a');
$btrace = debug_backtrace();
fputs($fp, $btrace[1]['file'] . ', ' . $btrace[1]['line'] . ":\n");
foreach ($GLOBALS as $key => $val)
{
if ($key != 'GLOBALS')
{
fputs($fp, "$key = " .print_r($val, TRUE) ."\n");
}
}
fputs($fp, "----------------\n");
fclose($fp);
}
/**
* Dumps variables in local scope into debug log file and continues normal script execution.
*
* @example eval(SED_CHECKPOINT_LOCALS);
* @see sed_checkpoint(), SED_DEBUG_LOGFILE, sed_watch(), SED_VARDUMP_LOCALS
*/
define('SED_CHECKPOINT_LOCALS', '$debug_fp = fopen(SED_DEBUG_LOGFILE, "a");
$debug_btrace = debug_backtrace();
fputs($debug_fp, $debug_btrace[0]["file"] . ", " . $debug_btrace[1]["line"] . ":\n");
$debug_vars = get_defined_vars();
foreach ($debug_vars as $debug_key => $debug_val)
{
if ($debug_key != "GLOBALS" && $debug_key != "debug_vars" && $debug_key != "debug_btrace" && $debug_key != "debug_fp")
{
fputs($debug_fp, "$debug_key = " .print_r($debug_val, TRUE) ."\n");
}
}
fputs($debug_fp, "----------------\n");
fclose($debug_fp);'
);
?>