)___(.*?)___(<\/code>)/s",
function ($aMatches) use (&$aCode) {
$sCode = isset($aCode[$aMatches[2]]) ? $aCode[$aMatches[2]] : 'n/a';
return $aMatches[1] . $sCode . $aMatches[3];
},
$s);
return $s;
}
/*
* This function apply bx_process_input and then bx_process_output.
* Use this function to output data immediately after receiving, without saving to database.
* Patams are the same as bx_process_input function - @see bx_process_input
*/
function bx_process_pass ($mixedData, $iDataType = BX_DATA_TEXT, $mixedParams = false, $isCheckMagicQuotes = true)
{
return bx_process_output(bx_process_input ($mixedData, $iDataType, $mixedParams, $isCheckMagicQuotes), $iDataType, $mixedParams);
}
/**
* DEPRECATED
* use bx_process_input + bx_process_output instead
* --------
* function for processing pass data
*
* This function cleans the GET/POST/COOKIE data if magic_quotes_gpc() is on
* for data which should be outputed immediately after submit
*/
/*
function process_pass_data( $text, $strip_tags = 0 )
{
if ( $strip_tags )
$text = strip_tags($text);
if ( !get_magic_quotes_gpc() )
return $text;
else
return stripslashes($text);
}
*/
/*
* function for output data from database into html
*/
function htmlspecialchars_adv( $string )
{
return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false);
}
/**
* Send mail to user by parsing email template
*/
function sendMailTemplate($sTemplateName, $iAccountId = 0, $iProfileId = 0, $aReplaceVars = array(), $iEmailType = BX_EMAIL_NOTIFY, $bAddToQueue = false)
{
$oProfile = $iProfileId ? BxDolProfile::getInstance($iProfileId) : null;
$oAccount = $iAccountId ? BxDolAccount::getInstance($iAccountId) : ($oProfile ? $oProfile->getAccountObject() : null);
$oEmailTemplates = BxDolEmailTemplates::getInstance();
if (!($oAccount || $oProfile) || !$oEmailTemplates)
return false;
$aTemplate = $oEmailTemplates->parseTemplate($sTemplateName, $aReplaceVars, $oAccount ? $oAccount->id() : 0, (int)$iProfileId);
if (!$aTemplate)
return false;
return sendMail($oAccount->getEmail(), $aTemplate['Subject'], $aTemplate['Body'], 0, array(), $iEmailType, 'html', false, array(), $bAddToQueue);
}
/**
* Send system email
*/
function sendMailTemplateSystem($sTemplateName, $aReplaceVars = array(), $iEmailType = BX_EMAIL_SYSTEM, $bAddToQueue = false)
{
$oEmailTemplates = BxDolEmailTemplates::getInstance();
if (!$oEmailTemplates)
return false;
$aTemplate = $oEmailTemplates->parseTemplate($sTemplateName, $aReplaceVars);
if (!$aTemplate)
return false;
return sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body'], 0, array(), $iEmailType, 'html', false, array(), $bAddToQueue);
}
/**
* Send email function
*
* @param $mRecipientEmails - Email where email should be send, can be array, string with one email or comma separated
* @param $sMailSubject - subject of the message
* @param $sMailBody - Body of the message
* @param $iRecipientID - ID of recipient profile
* @param $aPlus - Array of additional information
* @param $iEmailType - email message type: BX_EMAIL_SYSTEM, BX_EMAIL_NOTIFY or BX_EMAIL_MASS
* @param $sEmailFlag - use 'html' for HTML email message
* @param $isDisableAlert - disable alert
* @param $aCustomHeaders - custom email headers
* @param $bAddToQueue - add message to email queue
* @return true if message was send or false otherwise
*/
function sendMail($mRecipientEmails, $sMailSubject, $sMailBody, $iRecipientID = 0, $aPlus = array(), $iEmailType = BX_EMAIL_NOTIFY, $sEmailFlag = 'html', $isDisableAlert = false, $aCustomHeaders = array(), $bAddToQueue = false)
{
if (is_string($mRecipientEmails)){
if(strpos($mRecipientEmails, ',') !== false){
$mRecipientEmails = explode(',', $mRecipientEmails);
}
else{
return _sendMail($mRecipientEmails, $sMailSubject, $sMailBody, $iRecipientID, $aPlus, $iEmailType, $sEmailFlag, $isDisableAlert, $aCustomHeaders, $bAddToQueue);
}
}
if (is_array($mRecipientEmails)) {
$bReturn = false;
foreach($mRecipientEmails as $sRecipientEmail) {
$sRecipientEmail = trim($sRecipientEmail);
if (_sendMail($sRecipientEmail, $sMailSubject, $sMailBody, $iRecipientID, $aPlus, $iEmailType, $sEmailFlag, $isDisableAlert, $aCustomHeaders, $bAddToQueue))
$bReturn = true;
}
return $bReturn;
}
}
function _sendMail($sRecipientEmail, $sMailSubject, $sMailBody, $iRecipientID = 0, $aPlus = array(), $iEmailType = BX_EMAIL_NOTIFY, $sEmailFlag = 'html', $isDisableAlert = false, $aCustomHeaders = array(), $bAddToQueue = false)
{
// make sure that recipient's email is valid and message isn't empty
if (!$sMailBody || !$sRecipientEmail || preg_match('/\(2\)$/', $sRecipientEmail))
return false;
// get recipient account
$oAccount = !$isDisableAlert ? BxDolAccount::getInstance($sRecipientEmail) : null;
$aAccountInfo = $oAccount ? $oAccount->getInfo() : false;
// don't send bulk emails if user didn't subscribed to site news or email is unconfirmed
if ($aAccountInfo && BX_EMAIL_MASS == $iEmailType && (!$aAccountInfo['email_confirmed'] || !$aAccountInfo['receive_news']))
return false;
// don't send email notifications if user didn't subscribed to notifications or email is unconfirmed
if ($aAccountInfo && BX_EMAIL_NOTIFY == $iEmailType && (!$aAccountInfo['email_confirmed'] || !$aAccountInfo['receive_updates']))
return false;
// decode HTML entities in the subj
$sMailSubject = html_entity_decode($sMailSubject, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8');
if($bAddToQueue && BxDolQueueEmail::getInstance()->add($sRecipientEmail, $sMailSubject, $sMailBody, $iRecipientID, $aPlus, $iEmailType, $sEmailFlag, $isDisableAlert, $aCustomHeaders))
return true;
// if profile id is provided - get profile's info
$aRecipientInfo = false;
if ($iRecipientID) {
$oProfile = BxDolProfile::getInstance($iRecipientID);
if ($oProfile)
$aRecipientInfo = $oProfile->getInfo();
}
// get site vars
$sEmailNotify = !$isDisableAlert ? getParam('site_email_notify') : $sRecipientEmail;
$sSiteTitle = !$isDisableAlert ? getParam('site_title') : 'UNA ' . BX_DOL_VERSION;
// add unsubscribe link
if (!$isDisableAlert && empty($aPlus['unsubscribe'])) {
$aPlus['unsubscribe'] = '';
if ($oAccount && (BX_EMAIL_MASS == $iEmailType || BX_EMAIL_NOTIFY == $iEmailType))
$aPlus['unsubscribe'] = ($sLink = $oAccount->getUnsubscribeLink($iEmailType)) ? '' . _t('_sys_et_txt_unsubscribe') . '' : '';
}
// parse template
if ($aPlus || $iRecipientID || $oAccount) {
if(!is_array($aPlus))
$aPlus = [];
$oEmailTemplates = BxDolEmailTemplates::getInstance();
$sMailSubject = $oEmailTemplates->parseContent($sMailSubject, $aPlus, !$iRecipientID && $oAccount ? $oAccount->id() : 0, $iRecipientID);
$sMailBody = $oEmailTemplates->parseContent($sMailBody, $aPlus, !$iRecipientID && $oAccount ? $oAccount->id() : 0, $iRecipientID);
}
if(($sRootUrl = getParam('sys_api_url_root_email')) !== '') {
if(substr(BX_DOL_URL_ROOT, -1) == '/' && substr($sRootUrl, -1) != '/')
$sRootUrl .= '/';
$sMailBody = str_replace(BX_DOL_URL_ROOT, $sRootUrl, $sMailBody);
// restore URLs in images
$sMailBody = str_replace([
'src="' . $sRootUrl,
"src='" . $sRootUrl
], [
'src="' . BX_DOL_URL_ROOT,
"src='" . BX_DOL_URL_ROOT
], $sMailBody);
}
// email message headers
$sMailHeader = '';
foreach ($aCustomHeaders as $sHeaderName => $sHeaderValue)
$sMailHeader = "$sHeaderName: $sHeaderValue\r\n" . $sMailHeader;
if (!isset($aCustomHeaders['From']))
$sMailHeader = "From: =?UTF-8?B?" . base64_encode( $sSiteTitle ) . "?= <{$sEmailNotify}>";
if (!isset($aCustomHeaders['MIME-Version']))
$sMailHeader = "MIME-Version: 1.0\r\n" . $sMailHeader;
$sMailParameters = isset($aCustomHeaders['Sender']) ? "-f{$aCustomHeaders['Sender']}" : "-f{$sEmailNotify}";
if (isset($aCustomHeaders['Subject']))
$sMailSubject = $aCustomHeaders['Subject'];
// build data for alert handler
$bResult = null;
$aAlert = array(
'email' => $sRecipientEmail,
'subject' => $sMailSubject,
'body' => $sMailBody,
'header' => $sMailHeader,
'params' => $sMailParameters,
'recipient' => $aRecipientInfo,
'email_type' => $iEmailType,
'html' => 'html' == $sEmailFlag ? true : false,
'custom_headers' => $aCustomHeaders,
'override_result' => &$bResult,
);
/**
* @hooks
* @hookdef hook-system-check_send_mail 'system', 'check_send_mail' - hook for disabling mail sending
* - $unit_name - equals `system`
* - $action - equals `check_send_mail`
* - $object_id - recipient profile id
* - $sender_id - not used
* - $extra_params - array of additional params with the following array keys:
* - `email` - [string] recipient email
* - `subject` - [string] email subject
* - `body` - [string] email body
* - `header` - [string] email headers, headers are separated with double new line character
* - `params` - [string] parameters for php mail function
* - `recipient` - [array] recipient info array
* - `email_type` - [int] email type, one of the following BX_EMAIL_SYSTEM, BX_EMAIL_NOTIFY, BX_EMAIL_MASS
* - `html` - [boolean] `true` if email content is HTML, if `false` then email content is text
* - `custom_headers` - [array] custom email headers array as key&value pairs
* - `override_result` - [boolean] override result of `sendMail` function, if `true` then mail sending should continue as usual, if `false` then mail sending should stop
* @hook @ref hook-system-check_send_mail
*/
bx_alert('system', 'check_send_mail', (isset($aRecipientInfo['ID']) ? $aRecipientInfo['ID'] : 0), '', $aAlert);
if ($bResult !== null)
return $bResult;
// system alert
if (!$isDisableAlert) {
/**
* @hooks
* @hookdef hook-system-before_send_mail 'system', 'before_send_mail' - hook before mail sending
* It's equivalent to @ref hook-system-check_send_mail
* @hook @ref hook-system-before_send_mail
*/
bx_alert('system', 'before_send_mail', (isset($aRecipientInfo['ID']) ? $aRecipientInfo['ID'] : 0), '', $aAlert);
if ($bResult !== null)
return $bResult;
unset($aAlert['override_result']);
}
// prepare HTML/Plain message
if($sEmailFlag == 'html')
$sMailHeader = "Content-type: text/html; charset=UTF-8\r\n" . $sMailHeader;
else {
$sMailHeader = "Content-type: text/plain; charset=UTF-8\r\n" . $sMailHeader;
$sMailBody = html2txt($sMailBody);
}
// encode subject
if (0 !== strncasecmp($sMailSubject, '=?UTF-8?B?', 10))
$sMailSubject = '=?UTF-8?B?' . base64_encode($sMailSubject) . '?=';
// send mail or put it into queue
$bResult = mail($sRecipientEmail, $sMailSubject, $sMailBody, $sMailHeader, $sMailParameters);
// system alert
if (!$isDisableAlert) {
/**
* @hooks
* @hookdef hook-system-send_mail 'system', 'send_mail' - hook when mail was sent
* It's equivalent to @ref hook-system-check_send_mail
* except `override_result` parameter in $extra_params is missing
* @hook @ref hook-system-send_mail
*/
bx_alert('system', 'send_mail', (isset($aRecipientInfo['ID']) ? $aRecipientInfo['ID'] : 0), '', $aAlert);
}
return $bResult;
}
/*
* Getting an array with Templates' Names
*/
function get_templates_array($bEnabledOnly = true, $bShortInfo = true)
{
$oDb = BxDolDb::getInstance();
$sWhereAddon = $bEnabledOnly ? " AND `enabled`='1'" : "";
if($bShortInfo)
return $oDb->getPairs("SELECT `uri`, `title` FROM `sys_modules` WHERE 1 AND `type`='" . BX_DOL_MODULE_TYPE_TEMPLATE . "'" . $sWhereAddon, "uri", "title");
else
return $oDb->getAllWithKey("SELECT * FROM `sys_modules` WHERE 1 AND `type`='" . BX_DOL_MODULE_TYPE_TEMPLATE . "'" . $sWhereAddon, "uri");
}
function bx_get_image_exif_and_size($oStorage, $oTranscoder, $iContentId){
$sData = '';
$sExif = '';
$aExif = false;
$aPhoto = $oStorage->getFile($iContentId);
if ($oTranscoder->isMimeTypeSupported($aPhoto['mime_type'])) {
$oImageReize = BxDolImageResize::getInstance();
$a = $oImageReize->getImageSize($oTranscoder->getFileUrl($iContentId));
$sData = isset($a['w']) && isset($a['h']) ? $a['w'] . 'x' . $a['h'] : '';
if ($aExif = $oImageReize->getExifInfo($oStorage->getFileUrlById($iContentId))) {
$a = array('Make', 'Model', 'FocalLength', 'ShutterSpeedValue', 'ExposureTime', 'ISOSpeedRatings', 'Orientation', 'Artist', 'Copyright', 'Flash', 'WhiteBalance', 'DateTimeOriginal', 'DateTimeDigitized', 'ExifVersion', 'COMPUTED', 'GPSLatitudeRef', 'GPSLatitude', 'GPSLongitudeRef', 'GPSLongitude', 'GPSAltitudeRef', 'GPSAltitude', 'GPSTimeStamp', 'GPSImgDirectionRef', 'GPSImgDirection', 'GPSDateStamp');
$aExifFiltered = array();
foreach ($a as $sIndex)
if (isset($aExif[$sIndex]))
$aExifFiltered[$sIndex] = $aExif[$sIndex];
$sExif = serialize($aExifFiltered);
}
}
return array('exif' => $sExif, 'size' => $sData);
}
function bx_get_svg_image_size($sUrl)
{
$iWidth = $iHeight = 0;
$sContent = bx_file_get_contents($sUrl);
if(empty($sContent))
return [$iWidth, $iHeight];
$aAttributes = BxDolXmlParser::getInstance()->getAttributes($sContent, 'SVG', 0);
if(isset($aAttributes['VIEWBOX'])) {
$aViewBox = explode(' ', $aAttributes['VIEWBOX']);
if(!empty($aViewBox) && is_array($aViewBox) && count($aViewBox) == 4) {
$iWidth = (float)$aViewBox[2];
$iHeight = (float)$aViewBox[3];
}
}
if(!$iWidth && isset($aAttributes['WIDTH']))
$iWidth = (float)$aAttributes['WIDTH'];
if(!$iHeight && isset($aAttributes['HEIGHT']))
$iHeight = (float)$aAttributes['HEIGHT'];
return [$iWidth, $iHeight];
}
function extFileExists( $sFileSrc )
{
return (file_exists( $sFileSrc ) && is_file( $sFileSrc )) ? true : false;
}
function getVisitorIP()
{
$ip = "0.0.0.0";
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!isset( $_SERVER['HTTP_X_FORWARDED_FOR']) || empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
if (!isset( $_SERVER['HTTP_CLIENT_IP']) && empty($_SERVER['HTTP_CLIENT_IP']) && isset($_SERVER['REMOTE_ADDR']))
$ip = $_SERVER['REMOTE_ADDR'];
}
return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : "0.0.0.0";
}
function genFlag($sLang = '', $oTemplate = null)
{
if (!$oTemplate)
$oTemplate = BxDolTemplate::getInstance();
$oTemplate->addCss(BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flag-icons/css/|flag-icons.min.css');
$sFlag = BxDolLanguages::getInstance()->getLangFlag($sLang);
return '';
}
// print debug information ( e.g. arrays )
function echoDbg( $what, $desc = '' )
{
if ( $desc )
echo "$desc: ";
echo "";
print_r( $what );
echo "\n";
}
function echoDbgLog($mWhat, $sDesc = 'unused', $sFileName = 'unused')
{
bx_log('sys_debug', $mWhat, BX_LOG_DEBUG);
}
function bx_is_dbg()
{
return (defined('BX_DBG_COOKIE') && !empty($_COOKIE[BX_DBG_COOKIE])) || (defined('BX_DBG_PROFILES') && in_array(bx_get_logged_profile_id(), BX_DBG_PROFILES));
}
function dbgTiming($sStartMicrotime)
{
$i1 = explode(' ', microtime ());
$i2 = explode(' ', $sStartMicrotime);
$iTime = ($i1[0]+$i1[1]) - ($i2[0]+$i2[1]);
return round($iTime, 6) . ' sec';
}
function echoJson($a)
{
header('Content-Type: application/json; charset=utf-8');
echo json_encode($a);
}
function clear_xss($val)
{
// HTML Purifier plugin
global $logged;
global $oHtmlPurifier;
$bAdmin = isset($logged) && $logged['admin'];
if (!isset($oHtmlPurifier) && !$bAdmin) {
HTMLPurifier_Bootstrap::registerAutoload();
$oConfig = HTMLPurifier_Config::createDefault();
$oConfig->set('Cache.SerializerPath', rtrim(BX_DIRECTORY_PATH_CACHE, '/'));
$oConfig->set('Cache.SerializerPermissions', BX_DOL_DIR_RIGHTS);
$oConfig->set('HTML.SafeObject', 'true');
$oConfig->set('Output.FlashCompat', 'true');
$oConfig->set('HTML.FlashAllowFullScreen', 'true');
$oConfig->set('Attr.AllowedFrameTargets', array('_blank', '_self', '_parent', '_top'));
if (getParam('sys_add_nofollow')) {
$sHost = parse_url(BX_DOL_URL_ROOT, PHP_URL_HOST);
$oConfig->set('URI.Host', $sHost);
$oConfig->set('HTML.Nofollow', 'true');
}
$oConfig->set('Filter.Custom', array (
new BxDolHTMLPurifierFilterYouTube(),
new BxDolHTMLPurifierFilterYoutubeIframe(),
new BxDolHTMLPurifierFilterAddBxLinksClass(),
new BxDolHTMLPurifierFilterLocalIframe(),
new BxDolHTMLPurifierFilterEmbed(),
));
$oConfig->set('HTML.DefinitionID', 'html5-definitions');
$oConfig->set('HTML.DefinitionRev', 1);
if ($def = $oConfig->maybeGetRawHTMLDefinition()) {
$def->addElement('section', 'Block', 'Flow', 'Common');
$def->addElement('nav', 'Block', 'Flow', 'Common');
$def->addElement('article', 'Block', 'Flow', 'Common');
$def->addElement('aside', 'Block', 'Flow', 'Common');
$def->addElement('header', 'Block', 'Flow', 'Common');
$def->addElement('footer', 'Block', 'Flow', 'Common');
$def->addElement('video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array(
'src' => 'URI',
'type' => 'Text',
'width' => 'Length',
'height' => 'Length',
'poster' => 'URI',
'preload' => 'Enum#auto,metadata,none',
'controls' => 'Bool',
));
$def->addElement('source', 'Block', 'Flow', 'Common', array(
'src' => 'URI',
'type' => 'Text',
));
$def->addAttribute('a', 'data-profile-id', 'Text');
$def->addAttribute('a', 'dchar', 'Text');
$def->addAttribute('div', 'source', 'Text');
}
$oHtmlPurifier = new HTMLPurifier($oConfig);
}
/**
* Note. I'm not sure if double 'purify' is needed for non-admins.
*/
if(!$bAdmin)
$val = $oHtmlPurifier->purify($val);
$sNewVal = $val;
if(!$bAdmin)
$sNewVal = $oHtmlPurifier->purify($val);
/**
* @hooks
* @hookdef hook-account-clear_xss 'account', 'clear_xss' - hook after string is checked for xss
* - $unit_name - equals `system`
* - $action - equals `clear_xss`
* - $object_id - not used
* - $sender_id - not used
* - $extra_params - array of additional params with the following array keys:
* - `oHtmlPurifier` - [object] HtmlPurifier object
* - `input_data` - [string] string before check xss
* - `return_data` - [string] by ref, string before check xss, can be overridden in hook processing
* @hook @ref hook-system-clear_xss
*/
bx_alert('system', 'clear_xss', 0, 0, array('oHtmlPurifier' => $oHtmlPurifier, 'input_data' => $val, 'return_data' => &$sNewVal));
return $val;
}
//--------------------------------------- friendly permalinks --------------------------------------//
//------------------------------------------- main functions ---------------------------------------//
function uriGenerate ($sValue, $sTable, $sField, $aParams = [])
{
$sDivider = isset($aParams['divider']) ? $aParams['divider'] : '-';
$aCond = isset($aParams['cond']) && is_array($aParams['cond']) ? $aParams['cond'] : [];
$sValue = uriFilter($sValue, $aParams);
if(uriCheckUniq($sValue, $sTable, $sField, $aCond))
return $sValue;
// cut off redundant part
if(get_mb_len($sValue) > 240)
$sValue = get_mb_substr($sValue, 0, 240);
// try to add number
for($i = 0 ; $i < 999 ; ++$i) {
$iRnd = mt_rand(1000, 9999);
if(uriCheckUniq($sValue . $sDivider . $iRnd, $sTable, $sField, $aCond))
return ($sValue . $sDivider . $iRnd);
}
return rand(0, PHP_INT_MAX);
}
function uriFilter ($s, $aParams = [])
{
$sEmpty = isset($aParams['empty']) ? $aParams['empty'] : '-';
$sDivider = isset($aParams['divider']) ? $aParams['divider'] : '-';
if(BxTemplConfig::getInstance()->bAllowUnicodeInPreg)
$s = get_mb_replace ('/[^\pL^\pN^_]+/u', $sDivider, $s); // unicode characters
else
$s = get_mb_replace ('/([^\d^\w]+)/u', $sDivider, $s); // latin characters only
$s = get_mb_replace ('/([' . $sDivider . '^]+)/', $sDivider, $s);
$s = get_mb_replace ('/([' . $sDivider . ']+)$/', '', $s); // remove trailing dash
if(!$s)
$s = $sEmpty;
return !isset($aParams['lowercase']) || $aParams['lowercase'] === true ? mb_strtolower($s) : $s;
}
function uriCheckUniq ($sValue, $sTable, $sField, $aCond = [])
{
$oDb = BxDolDb::getInstance();
$sWhere = $aCond ? $oDb->arrayToSQL($aCond, ' AND ') : '1';
$sSql = $oDb->prepare("SELECT 1 FROM `$sTable` WHERE $sWhere AND `$sField`=? LIMIT 1", $sValue);
return !$oDb->query($sSql);
}
function get_mb_replace ($sPattern, $sReplace, $s)
{
return preg_replace ($sPattern, $sReplace, $s);
}
function get_mb_len ($s)
{
return (function_exists('mb_strlen')) ? mb_strlen($s) : strlen($s);
}
function get_mb_substr ($s, $iStart, $iLen)
{
return (function_exists('mb_substr')) ? mb_substr ($s, $iStart, $iLen) : substr ($s, $iStart, $iLen);
}
function bx_mb_substr_replace($s, $sReplace, $iPosStart, $iLength)
{
return mb_substr($s, 0, $iPosStart) . $sReplace . mb_substr($s, $iPosStart + $iLength);
}
function bx_mb_strpos ($s, $sReplacement, $iStart = 0)
{
return mb_strpos($s, $sReplacement, $iStart);
}
/**
* Import class file, it automatically detects class path by its prefix or module array/name
*
* @param $sClassName - full class name or class postfix(withoit prefix) in the case of module class
* @param $mixedModule - module array or module name in the case of module class
*/
function bx_import($sClassName, $mixedModule = array())
{
if (class_exists($sClassName, false))
return;
$aModule = false;
if ($mixedModule) {
if (is_array($mixedModule)) {
$aModule = $mixedModule;
} elseif (is_string($mixedModule)) {
$o = BxDolModule::getInstance($mixedModule);
$aModule = $o->_aModule;
} elseif (is_bool($mixedModule) && true === $mixedModule) {
$aModule = $GLOBALS['aModule'];
}
}
if ($aModule) {
if (class_exists($aModule['class_prefix'] . $sClassName, false))
return;
require_once (BX_DIRECTORY_PATH_MODULES . $aModule['path'] . 'classes/' . $aModule['class_prefix'] . $sClassName . '.php');
return;
}
if (0 === strncmp($sClassName, 'BxDol', 5)) {
if (0 === strncmp($sClassName, 'BxDolStudio', 11))
require_once(BX_DOL_DIR_STUDIO_CLASSES . $sClassName . '.php');
else
require_once(BX_DIRECTORY_PATH_CLASSES . $sClassName . '.php');
return;
}
if (0 === strncmp($sClassName, 'BxBase', 6)) {
if (0 === strncmp($sClassName, 'BxBaseMod', 9)) {
$aMatches = array();
if (preg_match('/BxBaseMod([A-Z][a-z]+)/', $sClassName, $aMatches)) {
require_once(BX_DIRECTORY_PATH_MODULES . 'base/' . strtolower($aMatches[1]) . '/classes/' . $sClassName . '.php');
return;
}
} if (0 === strncmp($sClassName, 'BxBaseStudio', 12)) {
require_once(BX_DOL_DIR_STUDIO_BASE . 'scripts/' . $sClassName . '.php');
return;
} else {
require_once(BX_DIRECTORY_PATH_BASE . 'scripts/' . $sClassName . '.php');
return;
}
}
if (0 === strncmp($sClassName, 'BxTempl', 7)) {
if(0 === strncmp($sClassName, 'BxTemplStudio', 13)) {
$sPath = BX_DIRECTORY_PATH_MODULES . BxDolStudioTemplate::getInstance()->getPath() . 'data/template/studio/scripts/' . $sClassName . '.php';
if (!file_exists($sPath))
$sPath = BX_DOL_DIR_STUDIO_BASE . 'scripts_templ/' . $sClassName . '.php';
} else {
$sPath = BX_DIRECTORY_PATH_MODULES . BxDolTemplate::getInstance()->getPath() . 'data/template/system/scripts/' . $sClassName . '.php';
}
if (file_exists($sPath)) {
require_once($sPath);
return;
}
else{
require_once(BX_DIRECTORY_PATH_BASE . 'scripts_templ/' . $sClassName . '.php');
return;
}
trigger_error ("bx_import fatal error: class (" . $sClassName . ") wasn't found", E_USER_ERROR);
}
}
/**
* used in spl_autoload_register() function, so no need to call bx_import for system classes
*/
function bx_autoload($sClassName)
{
if (0 === strncmp($sClassName, 'BxDol', 5) || 0 === strncmp($sClassName, 'BxBase', 6) || 0 === strncmp($sClassName, 'BxTempl', 7))
bx_import($sClassName);
}
/**
* Gets an instance of class pathing necessary parameters if it's necessary.
*
* @param string $sClassName class name.
* @param array $aParams an array of parameters to be pathed to the constructor of the class.
* @param array $mixedModule an array with module description. Is used when the requested class is located in some module.
* @return unknown
*/
function bx_instance($sClassName, $aParams = array(), $mixedModule = array())
{
if(isset($GLOBALS['bxDolClasses'][$sClassName]))
return $GLOBALS['bxDolClasses'][$sClassName];
if ($mixedModule) {
if (!is_array($mixedModule)) {
$o = BxDolModule::getInstance($mixedModule);
$mixedModule = $o->_aModule;
}
$sClassName = bx_ltrim_str($sClassName, $mixedModule['class_prefix']);
bx_import($sClassName, $mixedModule);
$sClassName = $mixedModule['class_prefix'] . $sClassName;
}
$oClass = new ReflectionClass($sClassName);
$GLOBALS['bxDolClasses'][$sClassName] = empty($aParams) ? $oClass->newInstance() : $oClass->newInstanceArgs($aParams);
return $GLOBALS['bxDolClasses'][$sClassName];
}
/**
* Escapes string/array ready to pass to js script with filtered symbols like ', " etc
*
* @param $mixedInput - string/array which should be filtered
* @param $iQuoteType - string escaping method: BX_ESCAPE_STR_AUTO(default), BX_ESCAPE_STR_APOS or BX_ESCAPE_STR_QUOTE
* @return converted string / array
*/
function bx_js_string ($mixedInput, $iQuoteType = BX_ESCAPE_STR_AUTO)
{
$aUnits = array(
"\n" => "\\n",
"\r" => "",
);
if (BX_ESCAPE_STR_APOS == $iQuoteType) {
$aUnits["'"] = "\\'";
$aUnits[''] = '';
} else {
$aUnits['"'] = '"';
$aUnits["'"] = ''';
$aUnits[""] = '</script>';
}
return str_replace(array_keys($aUnits), array_values($aUnits), $mixedInput);
}
/**
* Return input string/array ready to pass to html attribute with filtered symbols like ', " etc
*
* @param $mixedInput - string/array which should be filtered
* @param $iQuoteType - string escaping BX_ESCAPE_STR_AUTO, BX_ESCAPE_STR_APOS or BX_ESCAPE_STR_QUOTE
* @return converted string / array
*/
function bx_html_attribute ($mixedInput, $iQuoteType = BX_ESCAPE_STR_AUTO)
{
$aUnits = array ();
if (BX_ESCAPE_STR_APOS == $iQuoteType)
$aUnits["'"] = "\\'";
elseif (BX_ESCAPE_STR_QUOTE == $iQuoteType)
$aUnits['"'] = '"';
else
$aUnits = array("\"" => """, "'" => "'");
return str_replace(array_keys($aUnits), array_values($aUnits), $mixedInput);
}
/**
* Escapes string/array ready to pass to php script with filtered symbols like ', " etc
*
* @param mixed $mixedInput - string/array which should be filtered
* @return converted string / array
*/
function bx_php_string_apos ($mixedInput)
{
return str_replace("'", "\\'", $mixedInput);
}
function bx_php_string_quot ($mixedInput)
{
return str_replace('"', '\\"', $mixedInput);
}
/**
* Gets file contents by URL.
*
* @param string $sFileUrl - file URL to be read.
* @param array $aParams - an array of parameters to be pathed with URL.
* @param string $sMethod - post or get.
* @param array $aHeaders - custom headers.
* @param string $sHttpCode - HTTP code to return
* @param array $aBasicAuth - array with 'user' and 'password' for Basic HTTP Auth
* @return string the file's contents.
*/
function bx_file_get_contents($sFileUrl, $aParams = array(), $sMethod = 'get', $aHeaders = array(), &$sHttpCode = null, $aBasicAuth = array(), $iTimeout = 0, $aCustomCurlParams = array())
{
if(!in_array($sMethod, ['post', 'post-raw', 'post-json', 'post-json-object']))
$sFileUrl = bx_append_url_params($sFileUrl, $aParams);
$sResult = '';
if(function_exists('curl_init')) {
$rConnect = curl_init();
curl_setopt($rConnect, CURLOPT_USERAGENT, 'UNA ' . (defined('BX_DOL_VERSION') ? constant('BX_DOL_VERSION') : ''));
curl_setopt($rConnect, CURLOPT_TIMEOUT, BxDolDb::getInstance() ? getParam('sys_default_curl_timeout') : 10);
curl_setopt($rConnect, CURLOPT_URL, $sFileUrl);
curl_setopt($rConnect, CURLOPT_RETURNTRANSFER, 1);
if (0 !== $iTimeout) {
curl_setopt($rConnect, CURLOPT_CONNECTTIMEOUT, $iTimeout);
curl_setopt($rConnect, CURLOPT_TIMEOUT, $iTimeout);
}
if(getParam('sys_curl_ssl_allow_untrusted') == 'on'){
curl_setopt($rConnect, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($rConnect, CURLOPT_SSL_VERIFYHOST, false);
}
if (!ini_get('open_basedir'))
curl_setopt($rConnect, CURLOPT_FOLLOWLOCATION, 1);
if ($aBasicAuth)
curl_setopt($rConnect, CURLOPT_USERPWD, $aBasicAuth['user'] . ':' . $aBasicAuth['password']);
if ('post' == $sMethod) {
curl_setopt($rConnect, CURLOPT_POST, true);
curl_setopt($rConnect, CURLOPT_POSTFIELDS, http_build_query($aParams));
}
elseif ('post-raw' == $sMethod) {
curl_setopt($rConnect, CURLOPT_POST, true);
curl_setopt($rConnect, CURLOPT_POSTFIELDS, $aParams);
}
elseif ('post-json' == $sMethod) {
curl_setopt($rConnect, CURLOPT_POST, true);
curl_setopt($rConnect, CURLOPT_POSTFIELDS, json_encode($aParams));
$aHeaders[] = 'Content-Type: application/json';
}
elseif ('post-json-object' == $sMethod) {
curl_setopt($rConnect, CURLOPT_POST, true);
curl_setopt($rConnect, CURLOPT_POSTFIELDS, json_encode($aParams, JSON_FORCE_OBJECT));
$aHeaders[] = 'Content-Type: application/json';
}
elseif ($sMethod != 'get') {
curl_setopt($rConnect, CURLOPT_CUSTOMREQUEST, $sMethod);
}
if ($aHeaders)
curl_setopt($rConnect, CURLOPT_HTTPHEADER, $aHeaders);
if (defined('BX_DOL_URL_ROOT') && 0 === strpos($sFileUrl, BX_DOL_URL_ROOT)) {
curl_setopt($rConnect, CURLOPT_COOKIE, http_build_query($_COOKIE, '', '; ', PHP_QUERY_RFC3986));
}
if ($aCustomCurlParams)
foreach ($aCustomCurlParams as $sName => $mixedValue)
curl_setopt($rConnect, $sName, $mixedValue);
$sResult = curl_exec($rConnect);
if (curl_errno($rConnect) == 60) { // CURLE_SSL_CACERT
curl_setopt($rConnect, CURLOPT_CAINFO, BX_DIRECTORY_PATH_PLUGINS . 'curl/cacert/cacert.pem');
$sResult = curl_exec($rConnect);
}
if (NULL !== $sHttpCode)
$sHttpCode = curl_getinfo($rConnect, CURLINFO_HTTP_CODE);
}
else {
$iSaveTimeout = false;
if (0 !== $iTimeout) {
$iSaveTimeout = ini_get('default_socket_timeout');
ini_set('default_socket_timeout', $iTimeout);
}
$sResult = @file_get_contents($sFileUrl);
if (0 !== $iTimeout && false !== $iSaveTimeout) {
ini_set('default_socket_timeout', $iSaveTimeout);
}
}
return $sResult;
}
function bx_make_utf8($s)
{
// Test it and see if it is UTF-8 or not
if (false !== mb_detect_encoding($s, ["UTF-8"], true))
return $s;
$sEncoding = mb_detect_encoding($s, ['ASCII', 'BASE64', 'HTML-ENTITIES', 'Windows-1251', 'KOI8-R'], true);
if ($sEncoding === false)
return $s;
return mb_convert_encoding($s, "UTF-8", $sEncoding);
}
function bx_get_site_info($sSourceUrl, $aProcessAdditionalTags = array())
{
$aResult = array();
$sContent = bx_file_get_contents($sSourceUrl);
if ($sContent) {
$sCharset = '';
preg_match("//i", $sContent, $aMatch);
if (isset($aMatch[1]))
$sCharset = $aMatch[1];
$sContent = preg_replace("/