$iMaxLen) { $s = mb_substr($s, 0, $iMaxLen); $sTail = $sEllipsisSign; } return htmlspecialchars_adv($s) . $sTail; } function html2txt($content, $tags = "") { while($content != strip_tags($content, $tags)) { $content = strip_tags($content, $tags); } return $content; } /** * Functions to process user input. * DON'T use to process data before passing to SQL query - use db prepare instead @see BxDolDb::prepare. * It is ok to use bx_process_input and then db prepare. * @param $mixedData data to process * @param $iDataType how to handle data, possible valies: * @code * BX_DATA_INT - integer value * BX_DATA_FLOAT - float values * BX_DATA_CHECKBOX - 'on' or empty string * BX_DATA_TEXT - text data, single line (default) * BX_DATA_TEXT_MULTILINE - text data, multiple lines * BX_DATA_HTML - HTML data * BX_DATA_DATE - date data type stored as yyyy-mm-dd * BX_DATA_DATETIME - date/time data type stored as yyyy-mm-dd hh:mm:ss * BX_DATA_DATE_TS' - date data type stored as unixtimestamp * BX_DATA_DATETIME_TS - date/time data type stored as unixtimestamp * BX_DATA_DATE_TS_UTC - date data type stored as unixtimestamp from UTC time * BX_DATA_DATETIME_TS_UTC - date/time data type stored as unixtimestamp from UTC time * @endcode * @param $mixedParams optional parameters to pass for validation * @param $isCheckMagicQuotes deprecated * @return the filtered data, or FALSE if the filter fails. */ function bx_process_input ($mixedData, $iDataType = BX_DATA_TEXT, $mixedParams = false, $isCheckMagicQuotes = true) { if (is_array($mixedData)) { foreach ($mixedData as $k => $v) $mixedData[$k] = bx_process_input($v, $iDataType, $mixedParams); return $mixedData; } if (get_magic_quotes_gpc() && $isCheckMagicQuotes) $mixedData = stripslashes($mixedData); switch ($iDataType) { case BX_DATA_INT: return filter_var(trim($mixedData), FILTER_VALIDATE_INT); case BX_DATA_FLOAT: return filter_var(trim($mixedData), FILTER_VALIDATE_FLOAT); case BX_DATA_CHECKBOX: return 'on' == trim($mixedData) ? 'on' : ''; case BX_DATA_DATE: // maybe consider using strtotime $mixedData = trim($mixedData); if (!preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/', $mixedData)) return false; list($iYear, $iMonth, $iDay) = explode('-', $mixedData); // 1985-10-28 $iDay = intval($iDay); $iMonth = intval($iMonth); $iYear = intval($iYear); return sprintf("%04d-%02d-%02d", $iYear, $iMonth, $iDay); case BX_DATA_DATETIME: // maybe consider using strtotime $mixedData = trim($mixedData); if (!preg_match('#(\d+)\-(\d+)\-(\d+)[\sT]{1}(\d+):(\d+):(\d+)#', $mixedData, $m) && !preg_match('#(\d+)\-(\d+)\-(\d+)[\sT]{1}(\d+):(\d+)#', $mixedData, $m)) return bx_process_input ($mixedData, BX_DATA_DATE, $mixedParams, $isCheckMagicQuotes); $iDay = intval($m[3]); $iMonth = intval($m[2]); $iYear = intval($m[1]); $iH = intval($m[4]); $iM = intval($m[5]); $iS = isset($m[6]) ? intval($m[6]) : 0; return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $iYear, $iMonth, $iDay, $iH, $iM, $iS); // 1985-10-28 00:59:35 case BX_DATA_DATE_TS: case BX_DATA_DATE_TS_UTC: $mixedData = trim($mixedData); if (!preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/', $mixedData)) return false; list($iYear, $iMonth, $iDay) = explode('-', $mixedData); $iDay = intval($iDay); $iMonth = intval($iMonth); $iYear = intval($iYear); $sFunc = BX_DATA_DATE_TS_UTC == $iDataType ? 'gmmktime' : 'mktime'; $iRet = $sFunc (0, 0, 0, $iMonth, $iDay, $iYear); return $iRet > 0 ? $iRet : false; case BX_DATA_DATETIME_TS: case BX_DATA_DATETIME_TS_UTC: if (!preg_match('#(\d+)\-(\d+)\-(\d+)[\s]{1}(\d+):(\d+):(\d+)[\s]{1}([+\-\d:Z]+)#', $mixedData, $m) && !preg_match('#(\d+)\-(\d+)\-(\d+)[\sT]{1}(\d+):(\d+):(\d+)#', $mixedData, $m) && !preg_match('#(\d+)\-(\d+)\-(\d+)[\sT]{1}(\d+):(\d+)#', $mixedData, $m)) return bx_process_input ($mixedData, BX_DATA_DATETIME_TS == $iDataType ? BX_DATA_DATE_TS : BX_DATA_DATE_TS_UTC, $mixedParams, $isCheckMagicQuotes); $iDay = $m[3]; $iMonth = $m[2]; $iYear = $m[1]; $iH = $m[4]; $iM = $m[5]; $iS = isset($m[6]) ? $m[6] : 0; $iTimezoneOffset = 0; if (isset($m[7])) { $oTz = new DateTimeZone($m[7]); $oUtc = new DateTime(str_replace($m[7], '', $mixedData), new DateTimeZone('UTC')); if ($oTz && $oUtc) $iTimezoneOffset = $oTz->getOffset($oUtc); } $sFunc = BX_DATA_DATETIME_TS_UTC == $iDataType ? 'gmmktime' : 'mktime'; $iRet = $sFunc ($iH, $iM, $iS, $iMonth, $iDay, $iYear) - $iTimezoneOffset; return $iRet > 0 ? $iRet : false; case BX_DATA_HTML: return clear_xss($mixedData); case BX_DATA_TEXT_MULTILINE: return nl2br(htmlspecialchars_adv($mixedData)); case BX_DATA_TEXT: default: return $mixedData; } } /* * Functions to process user output. * Always use this function before output data which was entered by user before. * @param $mixedData string to process * @param $iDataType how to handle data, possible valies the same as in bx_process_input function, see bx_process_input. * @param $mixedParams optional parameters to pass for validation * @return the filtered data, or FALSE if the filter fails. */ function bx_process_output ($mixedData, $iDataType = BX_DATA_TEXT, $mixedParams = false) { if (is_array($mixedData)) { foreach ($mixedData as $k => $v) $mixedData[$k] = bx_process_output($v, $iDataType, $mixedParams); return $mixedData; } switch ($iDataType) { case BX_DATA_INT: return filter_var($mixedData, FILTER_VALIDATE_INT); case BX_DATA_FLOAT: return filter_var($mixedData, FILTER_VALIDATE_FLOAT); case BX_DATA_CHECKBOX: return 'on' == trim($mixedData) ? 'on' : ''; case BX_DATA_DATE: case BX_DATA_DATETIME: return $mixedData; case BX_DATA_DATE_TS: return empty($mixedData) ? '' : date("Y-m-d", (int)$mixedData); case BX_DATA_DATE_TS_UTC: return empty($mixedData) ? '' : gmdate("Y-m-d", (int)$mixedData); case BX_DATA_DATETIME_TS: return empty($mixedData) ? '' : date("Y-m-d H:i", (int)$mixedData); case BX_DATA_DATETIME_TS_UTC: return empty($mixedData) ? '' : gmdate("Y-m-d H:i", (int)$mixedData); case BX_DATA_HTML: return bx_linkify_html($mixedData, 'class="' . BX_DOL_LINK_CLASS . '"'); case BX_DATA_TEXT_MULTILINE: return $mixedData; case BX_DATA_TEXT: default: return htmlspecialchars_adv($mixedData); } } /* * 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 = BxDolProfile::getInstance($iProfileId); $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 $sRecipientEmail - Email where email should be send * @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($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; 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 = array(); $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); } // 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, 'html' => 'html' == $sEmailFlag ? true : false, 'custom_headers' => $aCustomHeaders, 'override_result' => &$bResult, ); // system alert if (!$isDisableAlert) { 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) 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 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 = explode(".",$_SERVER['HTTP_CLIENT_IP']); $ip = $ip[3].".".$ip[2].".".$ip[1].".".$ip[0]; } 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 $ip; } function genFlag($sLang = '', $oTemplate = null) { if (!$oTemplate) $oTemplate = BxDolTemplate::getInstance(); $oTemplate->addCss(BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flag-icon-css/css/|flag-icon.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 = '', $sFileName = 'debug.log') { $sCont = '--- ' . date('r') . ' (' . BX_DOL_START . ") ---\n" . $sDesc . "\n" . print_r($mWhat, true) . "\n\n\n"; $rFile = fopen(BX_DIRECTORY_PATH_LOGS . $sFileName, 'a'); fwrite($rFile, $sCont); fclose($rFile); } function dbgTiming($sStartMicrotime) { $i1 = explode(' ', microtime ()); $i2 = explode(' ', $sStartMicrotime); $iTime = ($i1[0]+$i1[1]) - ($i2[0]+$i2[1]); return round($iTime, 3) . ' sec'; } function echoJson($a) { header('Content-type: text/html; charset=utf-8'); echo json_encode($a); } function clear_xss($val) { // HTML Purifier plugin global $oHtmlPurifier; if (!isset($oHtmlPurifier) && !$GLOBALS['logged']['admin']) { require_once( BX_DIRECTORY_PATH_PLUGINS . 'htmlpurifier/HTMLPurifier.standalone.php' ); 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 HTMLPurifier_Filter_YouTube(), new HTMLPurifier_Filter_YoutubeIframe(), new HTMLPurifier_Filter_AddBxLinksClass(), new HTMLPurifier_Filter_LocalIframe())); $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', 'Number'); } $oHtmlPurifier = new HTMLPurifier($oConfig); } if (!$GLOBALS['logged']['admin']) $val = $oHtmlPurifier->purify($val); bx_alert('system', 'clear_xss', 0, 0, array('oHtmlPurifier' => $oHtmlPurifier, 'return_data' => &$val)); return $val; } //--------------------------------------- friendly permalinks --------------------------------------// //------------------------------------------- main functions ---------------------------------------// function uriGenerate ($s, $sTable, $sField, $sEmpty = '-', $sDivider = '-') { $s = uriFilter($s, $sEmpty, $sDivider); if(uriCheckUniq($s, $sTable, $sField)) return $s; // cut off redundant part if(get_mb_len($s) > 240) $s = get_mb_substr($s, 0, 240); // try to add date $s .= $sDivider . date('Y-m-d'); if(uriCheckUniq($s, $sTable, $sField)) return $s; // try to add number for($i = 0 ; $i < 999 ; ++$i) if(uriCheckUniq($s . $sDivider . $i, $sTable, $sField)) return ($s . $sDivider . $i); return rand(0, 999999999); } function uriFilter ($s, $sEmpty = '-', $sDivider = '-') { 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 $s; } function uriCheckUniq ($s, $sTable, $sField) { $oDb = BxDolDb::getInstance(); $sSql = $oDb->prepare("SELECT 1 FROM `$sTable` WHERE `$sField`=? LIMIT 1", $s); 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'; } else { $sPath = BX_DIRECTORY_PATH_MODULES . BxDolTemplate::getInstance()->getPath() . 'data/template/system/scripts/' . $sClassName . '.php'; } if (file_exists($sPath)) { require_once($sPath); 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[''] = ""; } elseif (BX_ESCAPE_STR_QUOTE == $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 ('post' != $sMethod) $sFileUrl = bx_append_url_params($sFileUrl, $aParams); $sResult = ''; if(function_exists('curl_init')) { $rConnect = curl_init(); curl_setopt($rConnect, CURLOPT_USERAGENT, 'UNA ' . BX_DOL_VERSION); curl_setopt($rConnect, CURLOPT_TIMEOUT, 10); curl_setopt($rConnect, CURLOPT_URL, $sFileUrl); curl_setopt($rConnect, CURLOPT_HEADER, NULL === $sHttpCode ? false : true); curl_setopt($rConnect, CURLOPT_RETURNTRANSFER, 1); if (0 !== $iTimeout) { curl_setopt($rConnect, CURLOPT_CONNECTTIMEOUT, $iTimeout); curl_setopt($rConnect, CURLOPT_TIMEOUT, $iTimeout); } if (!ini_get('open_basedir')) curl_setopt($rConnect, CURLOPT_FOLLOWLOCATION, 1); if ($aHeaders) curl_setopt($rConnect, CURLOPT_HTTPHEADER, $aHeaders); 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)); } $sAllCookies = ''; foreach($_COOKIE as $sKey=>$sValue){ $sAllCookies .= $sKey . '=' . $sValue . ';'; } curl_setopt($rConnect, CURLOPT_COOKIE, $sAllCookies); if ($aCustomCurlParams) foreach ($aCustomCurlParams as $sName => $mixedValue) curl_setopt($rConnect, constant($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.pem'); $sResult = curl_exec($rConnect); } if (NULL !== $sHttpCode) $sHttpCode = curl_getinfo($rConnect, CURLINFO_HTTP_CODE); curl_close($rConnect); } 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_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("/]*>(.*?)<\/script>/i", '', $sContent); $sContent = preg_replace("/]*>(.*?)<\/style>/i", '', $sContent); if (preg_match("/]*>(.*?)<\/title>/i", $sContent, $aMatch)) $aResult['title'] = strip_tags($aMatch[1]); else $aResult['title'] = parse_url($sSourceUrl, PHP_URL_HOST); $aResult['description'] = bx_parse_html_tag($sContent, 'meta', 'name', 'description', 'content', $sCharset); $aResult['keywords'] = bx_parse_html_tag($sContent, 'meta', 'name', 'keywords', 'content', $sCharset); if ($aProcessAdditionalTags) { foreach ($aProcessAdditionalTags as $k => $a) { $aResult[$k] = bx_parse_html_tag( $sContent, isset($a['tag']) ? $a['tag'] : 'meta', isset($a['name_attr']) ? $a['name_attr'] : 'itemprop', isset($a['name']) ? $a['name'] : $k, isset($a['content_attr']) ? $a['content_attr'] : 'content', $sCharset, isset($a['specialchars_decode']) ? $a['specialchars_decode'] : true); if ((isset($a['name']) && 'og:image' == $a['name']) || (isset($a['tag']) && 'link' == $a['tag'])) { $aResult[$k] = bx_get_site_info_fix_relative_url ($sSourceUrl, $aResult[$k]); } } } } return $aResult; } /** * Fix relative URL to make it absolute * @param $sSourceUrl main URL * @param $s URL to fix * @return absolute URL or URL wothout changes */ function bx_get_site_info_fix_relative_url ($sSourceUrl, $s) { if (0 === stripos($s, 'http://') || 0 === stripos($s, 'https://') || 0 === stripos($s, 'ftp://') || !$s) return $s; if ('/' == $s[0]) { $a = parse_url($sSourceUrl); return $a['scheme'] . '://' . $a['host'] . (empty($a['port']) || 80 == $a['port'] || 443 == $a['port'] ? '' : ':' . $a['port']) . $s; } return $sSourceUrl . ('/' === substr($sSourceUrl, -1) ? $s : '/' . $s); } function bx_parse_html_tag ($sContent, $sTag, $sAttrNameName, $sAttrNameValue, $sAttrContentName, $sCharset = false, $bSpecialCharsDecode = true) { if (!preg_match("/<{$sTag}\s+{$sAttrNameName}[='\" ]+{$sAttrNameValue}['\"]\s+{$sAttrContentName}[='\" ]+([^'>\"]*)['\"][^>]*>/i", $sContent, $aMatch) || !isset($aMatch[1])) preg_match("/<{$sTag}\s+{$sAttrContentName}[='\" ]+([^'>\"]*)['\"]\s+{$sAttrNameName}[='\" ]+{$sAttrNameValue}['\"][^>]*>/i", $sContent, $aMatch); $s = isset($aMatch[1]) ? $aMatch[1] : ''; if ($s && $sCharset) $s = mb_convert_encoding($s, 'UTF-8', $sCharset); if ($bSpecialCharsDecode) $s = htmlspecialchars_decode($s); return $s; } // calculation ini_get('upload_max_filesize') in bytes as example function return_bytes($val) { $val = trim($val); $last = strtolower($val{strlen($val)-1}); $val = (int)$val; switch($last) { // The 'G' modifier is available since PHP 5.1.0 case 'k': $val *= 1024; break; case 'm': $val *= 1024 * 1024; break; case 'g': $val *= 1024 * 1024 * 1024; break; } return $val; } // Generate Random Password function genRndPwd($iLength = 8, $bSpecialCharacters = true) { $sPassword = ''; $sChars = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"; if($bSpecialCharacters === true) $sChars .= "!?=/&+,."; for($i = 0; $i < $iLength; $i++) { $x = mt_rand(0, strlen($sChars) -1); $sPassword .= $sChars{$x}; } return $sPassword; } // Generate Random Salt for Password encryption function genRndSalt() { return genRndPwd(8, true); } /** * Encrypt user password. * When BX_PWD_ALGO is 'custom', then bx_custom_pwd_encrypt function with custom algorythm must be defined in inc/header.inc.php file. * @param $sPwd clear password * @param $sSalt salt * @return password hash */ function encryptUserPwd($sPwd, $sSalt) { $sAlgo = defined('BX_PWD_ALGO') ? BX_PWD_ALGO : ''; switch ($sAlgo) { case 'custom': return bx_custom_pwd_encrypt($sPwd, $sSalt); case 'crypt': return crypt($sPwd, BX_PWD_ALGO_SALT); case 'sha1_crypt_salt': return sha1(crypt($sPwd, BX_PWD_ALGO_SALT) . $sSalt); case 'sha1_md5_salt': default: return sha1(md5($sPwd) . $sSalt); } } function bx_get ($sName, $sMethod = false) { if (isset($_GET[$sName]) && ('get' == $sMethod || !$sMethod)) return $_GET[$sName]; elseif (isset($_POST[$sName]) && ('post' == $sMethod || !$sMethod)) return $_POST[$sName]; else return false; } function bx_get_base_url_inline($aParams = array()) { $aBaseLink = parse_url(BX_DOL_URL_ROOT); $sPageLink = (!empty($aBaseLink['scheme']) ? $aBaseLink['scheme'] : 'http') . '://' . $aBaseLink['host'] . $_SERVER['REQUEST_URI']; list($sPageLink, $aPageParams) = bx_get_base_url($sPageLink); if(!empty($_SERVER['QUERY_STRING'])) { $aPageParamsAdd = array(); parse_str($_SERVER['QUERY_STRING'], $aPageParamsAdd); if(!empty($aPageParamsAdd) && is_array($aPageParamsAdd)) $aPageParams = array_merge($aPageParams, $aPageParamsAdd); } if(!empty($aParams) && is_array($aParams)) $aPageParams = array_merge($aPageParams, $aParams); return array($sPageLink, $aPageParams); } function bx_get_base_url_popup($aParams = array()) { list($sPageLink, $aPageParams) = bx_get_base_url($_SERVER['HTTP_REFERER']); if(!empty($aParams) && is_array($aParams)) $aPageParams = array_merge($aPageParams, $aParams); return array($sPageLink, $aPageParams); } function bx_get_base_url($sPageLink) { $sPageLink = BxDolPermalinks::getInstance()->unpermalink($sPageLink, false); $sPageParams = ''; if(strpos($sPageLink, '?') !== false) list($sPageLink, $sPageParams) = explode('?', $sPageLink); $aPageParams = array(); if(!empty($sPageParams)) parse_str($sPageParams, $aPageParams); return array($sPageLink, $aPageParams); } function bx_get_location_bounds_latlng($fLatitude, $fLongitude, $iRadiusInKm) { $fEquatorLatInKm = 111.321; $aRv = array(); $aRv['max_lat'] = $fLatitude + $iRadiusInKm / $fEquatorLatInKm; $aRv['min_lat'] = $fLatitude - ($aRv['max_lat'] - $fLatitude); $aRv['max_lng'] = $fLongitude + $iRadiusInKm / (cos($aRv['min_lat'] * M_PI / 180) * $fEquatorLatInKm); $aRv['min_lng'] = $fLongitude - ($aRv['max_lng'] - $fLongitude); return $aRv; } function bx_encode_url_params ($a, $aExcludeKeys = array (), $aOnlyKeys = false) { $s = ''; foreach ($a as $sKey => $sVal) { if (in_array($sKey, $aExcludeKeys)) continue; if (false !== $aOnlyKeys && !in_array($sKey, $aOnlyKeys)) continue; if (is_array($sVal)) { foreach ($sVal as $sSubVal) { $s .= rawurlencode($sKey) . '[]=' . rawurlencode(is_array($sSubVal) ? 'array' : $sSubVal) . '&'; } } else { $s .= rawurlencode($sKey) . '=' . rawurlencode($sVal) . '&'; } } return $s; } function bx_append_url_params ($sUrl, $mixedParams) { if (!$mixedParams) return $sUrl; $sParams = false == strpos($sUrl, '?') ? '?' : '&'; if (is_array($mixedParams)) { foreach($mixedParams as $sKey => $sValue) { if (!is_array($sValue)) { $sParams .= $sKey . '=' . $sValue . '&'; } else { foreach($sValue as $sSubValue) $sParams .= $sKey . '[]=' . $sSubValue . '&'; } } $sParams = substr($sParams, 0, -1); } else { $sParams .= $mixedParams; } return $sUrl . $sParams; } function bx_rrmdir($directory) { if (substr($directory,-1) == "/") $directory = substr($directory,0,-1); if (!file_exists($directory) || !is_dir($directory)) return false; elseif (!is_readable($directory)) return false; if (!($directoryHandle = opendir($directory))) return false; while ($contents = readdir($directoryHandle)) { if ($contents != '.' && $contents != '..') { $path = $directory . "/" . $contents; if (is_dir($path)) bx_rrmdir($path); else unlink($path); } } closedir($directoryHandle); if (!rmdir($directory)) return false; return true; } function bx_clear_folder ($sPath, $aExts = array ()) { if (substr($$sPath,-1) == "/") $sPath = substr($sPath,0,-1); if (!file_exists($sPath) || !is_dir($sPath)) return false; elseif (!is_readable($sPath)) return false; if (!($h = opendir($sPath))) return false; while ($sFile = readdir($h)) { if ('.' == $sFile || '..' == $sFile) continue; $sFullPath = $sPath . '/' . $sFile; if (is_dir($sFullPath)) continue; if (!$aExts || (($sExt = pathinfo($sFullPath, PATHINFO_EXTENSION)) && in_array($sExt, $aExts))) @unlink($sFullPath); } closedir($h); return true; } function bx_ltrim_str ($sString, $sPrefix, $sReplace = '') { if ($sReplace && substr($sString, 0, strlen($sReplace)) == $sReplace) return $sString; if (substr($sString, 0, strlen($sPrefix)) == $sPrefix) return $sReplace . substr($sString, strlen($sPrefix)); return $sString; } function bx_rtrim_str ($sString, $sPrefix, $sReplace = '') { if ($sReplace && substr($sString, -strlen($sReplace)) == $sReplace) return $sString; if (substr($sString, -strlen($sPrefix)) == $sPrefix) return substr($sString, 0, -strlen($sPrefix)) . $sReplace; return $sString; } /** * Strip all lines with no information for example:

,

*/ function bx_trim_nl_duplicates($s) { $sStrip = implode('', array_keys(get_html_translation_table(HTML_ENTITIES))); return implode('', array_filter(mb_split("[\n\r]", $s), function($s) use ($sStrip) { return trim(strip_tags($s, '