<?php
/**
* BreezingForms - A Joomla Forms Application
* @version 1.8
* @package BreezingForms
* @copyright (C) 2008-2012 by Markus Bopp
* @license Released under the terms of the GNU General Public License
**/

defined('_JEXEC') or die('Direct Access to this location is not allowed.');

function bf_alert($content, $url = '#'){

    static $css;
    
    if(!$css){
    
    JFactory::getDocument()->addStyleDeclaration('/* Alert */
        .bfAlert {
            background-color: #c4453c;
            background-image: -webkit-linear-gradient(135deg, transparent,
                              transparent 25%, hsla(0,0%,0%,.05) 25%,
                              hsla(0,0%,0%,.05) 50%, transparent 50%,
                              transparent 75%, hsla(0,0%,0%,.05) 75%,
                              hsla(0,0%,0%,.05));
            background-image: -moz-linear-gradient(135deg, transparent,
                              transparent 25%, hsla(0,0%,0%,.1) 25%,
                              hsla(0,0%,0%,.1) 50%, transparent 50%,
                              transparent 75%, hsla(0,0%,0%,.1) 75%,
                              hsla(0,0%,0%,.1));
            background-image: -ms-linear-gradient(135deg, transparent,
                              transparent 25%, hsla(0,0%,0%,.1) 25%,
                              hsla(0,0%,0%,.1) 50%, transparent 50%,
                              transparent 75%, hsla(0,0%,0%,.1) 75%,
                              hsla(0,0%,0%,.1));
            background-image: -o-linear-gradient(135deg, transparent,
                              transparent 25%, hsla(0,0%,0%,.1) 25%,
                              hsla(0,0%,0%,.1) 50%, transparent 50%,
                              transparent 75%, hsla(0,0%,0%,.1) 75%,
                              hsla(0,0%,0%,.1));
            background-image: linear-gradient(135deg, transparent,
                              transparent 25%, hsla(0,0%,0%,.1) 25%,
                              hsla(0,0%,0%,.1) 50%, transparent 50%,
                              transparent 75%, hsla(0,0%,0%,.1) 75%,
                              hsla(0,0%,0%,.1));
            background-size: 20px 20px;
            box-shadow: 0 5px 0 hsla(0,0%,0%,.1);
            color: #ffffff !important;
            display: block;
            font: bold 16px/40px sans-serif;
            height: 40px;
            position: relative;
            text-align: center;
            text-decoration: none;
            top: -45px;
            width: 100%;
            -webkit-animation: bfAlert 1s ease forwards;
               -moz-animation: bfAlert 1s ease forwards;
                -ms-animation: bfAlert 1s ease forwards;
                 -o-animation: bfAlert 1s ease forwards;
                    animation: bfAlert 1s ease forwards;
        }

        /* Animation */

        @-webkit-keyframes bfAlert {
            0% { opacity: 0; }
            50% { opacity: 1; }
            100% { top: 0; } 
        }
        @-moz-keyframes bfAlert {
            0% { opacity: 0; }
            50% { opacity: 1; }
            100% { top: 0; }
        }
        @-ms-keyframes bfAlert {
            0% { opacity: 0; }
            50% { opacity: 1; }
            100% { top: 0; }
        }
        @-o-keyframes bfAlert {
            0% { opacity: 0; }
            50% { opacity: 1; }
            100% { top: 0; }
        }
        @keyframes bfAlert {
            0% { opacity: 0; }
            50% { opacity: 1; }
            100% { top: 0; }
        }');
    
        $css = true;
    
    }
    
    return '
    <div style="clear:both;"><a class="bfAlert" href="'.$url.'" rel="nofollow">'.htmlentities($content, ENT_QUOTES,'UTF-8').'</a></div>
    ';
}

function bf_tooltipText($title = '', $content = '', $translate = 1, $escape = 1)
{
        // Return empty in no title or content is given.
        if ($title == '' && $content == '')
        {
                return '';
        }

        // Split title into title and content if the title contains '::' (old Mootools format).
        if ($content == '' && !(strpos($title, '::') === false))
        {
                list($title, $content) = explode('::', $title, 2);
        }

        // Pass texts through the JText.
        if ($translate)
        {
                $title = JText::_($title);
                $content = JText::_($content);
        }

        // Escape the texts.
        if ($escape)
        {
                $title = str_replace('"', '&quot;', $title);
                $content = str_replace('"', '&quot;', $content);
        }

        // Return only the content if no title is given.
        if ($title == '')
        {
                return $content;
        }

        // Return only the title if title and text are the same.
        if ($title == $content)
        {
                return '<strong>' . $title . '</strong>';
        }

        // Return the formated sting combining the title and  content.
        if ($content != '')
        {
                return '<strong>' . $title . '</strong><br />' . $content;
        }

        // Return only the title.
        return $title;
}

function bf_stringURLUnicodeSlug($string)
{
        // Replace double byte whitespaces by single byte (East Asian languages)
        $str = preg_replace('/\xE3\x80\x80/', ' ', $string);


        // Remove any '-' from the string as they will be used as concatenator.
        // Would be great to let the spaces in but only Firefox is friendly with this

        $str = str_replace('-', ' ', $str);

        // Replace forbidden characters by whitespaces
        $str = preg_replace( '#[:\#\*"@+=;!&\.%()\]\/\'\\\\|\[]#',"\x20", $str );

        // Delete all '?'
        $str = str_replace('?', '', $str);

        // Trim white spaces at beginning and end of alias and make lowercase
        $str = trim(JString::strtolower($str));

        // Remove any duplicate whitespace and replace whitespaces by hyphens
        $str =preg_replace('#\x20+#','-', $str);

        return $str;
}

function bf_cleanString($string){
    return str_replace(array('[',']','{','}','(',')','|'), array('&#91;','&#93;','&#123;','&#125;','&#40;','&#41;','&#124;'), $string);
}

function bf_startsWith($haystack, $needle)
{
    $length = strlen($needle);
    return (substr($haystack, 0, $length) === $needle);
}

function bf_endsWith($haystack, $needle)
{
    $length = strlen($needle);
    if ($length == 0) {
        return true;
    }

    return (substr($haystack, -$length) === $needle);
}


function bf_is_mobile() {
    $is_mobile = false;

    // Check user agent string
    $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';

    if (empty($agent)) {
        return false;
    }

    $mobile_devices = array(
        'is_iphone' => 'iphone',
        'is_ipad' => 'ipad',
        'is_ipod' => 'ipod',
        'is_kindle' => 'kindle',
        'is_surface' => 'Windows NT [0-9.]+; ARM;',
        'is_windows_phone' => 'Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7'
    );

    $mobile_oss = array(
        'is_ios' => 'ip(hone|ad|od)',
        'is_android' => 'android',
        'is_webos' => '(web|hpw)os',
        'is_palmos' => 'palm(\s?os|source)',
        'is_windows' => 'windows (phone|ce)',
        'is_symbian' => 'symbian(\s?os|)|symbos',
        'is_bbos' => 'blackberry(.*?version\/\d+|\d+\/\d+)',
        'is_bada' => 'bada'
    );

    $mobile_browsers = array(
        'is_opera_mobile' => 'opera (mobi|mini)', // Opera Mobile or Mini
        'is_webkit_mobile' => '(android|nokia|webos|hpwos|blackberry).*?webkit|webkit.*?(mobile|kindle|bolt|skyfire|dolfin|iris)', // Webkit mobile
        'is_firefox_mobile' => 'fennec', // Firefox mobile
        'is_ie_mobile' => 'iemobile|windows ce', // IE mobile
        'is_netfront' => 'netfront|kindle|psp|blazer|jasmine', // Netfront
        'is_uc_browser' => 'ucweb' // UC browser
    );

    $groups = array($mobile_devices, $mobile_oss, $mobile_browsers);

    foreach ($groups as $group) {
        foreach ($group as $name => $regex) {
            if (preg_match('/' . $regex . '/i', $agent)) {
                $is_mobile = true;
                break;
            }
        }
    }

    // Fallbacks
    if ($is_mobile === false) {
        
        $useragent=$_SERVER['HTTP_USER_AGENT'];
        if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)))
        {
            return true;
        }
        
        $regex = 'nokia|motorola|sony|ericsson|lge?(-|;|\/|\s)|htc|samsung|asus|mobile|phone|tablet|pocket|wap|wireless|up\.browser|up\.link|j2me|midp|cldc|kddi|mmp|obigo|novarra|teleca|openwave|uzardweb|pre\/|hiptop|avantgo|plucker|xiino|elaine|vodafone|sprint|o2';
        $accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : '';

        if (false !== strpos($accept, 'text/vnd.wap.wml')
                || false !== strpos($accept, 'application/vnd.wap.xhtml+xml')
                || isset($_SERVER['HTTP_X_WAP_PROFILE'])
                || isset($_SERVER['HTTP_PROFILE'])
                || preg_match('/' . $regex . '/i', $agent)
        ) {
            $is_mobile = true;
        }
    }
    
    return $is_mobile;
}

/**
 * Mail creator as expected by former FacileForms code
 * This is a not really Legacy, so it stays like that
 *
 * @param string $from
 * @param string $fromname
 * @param string $subject
 * @param string $body
 * @return JMail
 */

function bf_getFieldSelectorList($form_id, $element_target_id){
    $db = JFactory::getDBO();
    $db->setQuery("Select `name` From #__facileforms_elements Where form = " . intval($form_id) . " And `name` Not In ('bfFakeName','bfFakeName2','bfFakeName3','bfFakeName4','bfFakeName5','bfFakeName6') Order by `ordering`");
    jimport('joomla.version');
    $version = new JVersion();
    if(version_compare($version->getShortVersion(), '3.0', '>=')){
        $rows = $db->loadColumn();
    }else{
        $rows = $db->loadResultArray();
    }
    $out = '<script type="text/javascript">
    function insertAtCursor_'.$element_target_id.'(myValue) {
var myField = document.getElementById("'.$element_target_id.'");
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA/NETSCAPE support
else if (myField.selectionStart || myField.selectionStart == \'0\') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}

    </script>';
    if($rows){
        foreach($rows As $row){
            $out .= '<a href="javascript: insertAtCursor_'.$element_target_id.'(\'{'.$row.':label}\');void(0);">{'.$row.':label}</a><br/>';
            $out .= '<a href="javascript: insertAtCursor_'.$element_target_id.'(\'{'.$row.':value}\');void(0);">{'.$row.':value}</a><br/><br/>';
        }
    }
    return $out;
}

function bf_getFieldSelectorListHTML($form_id, $editor, $element_target_id){
    $db = JFactory::getDBO();
    $db->setQuery("Select `name` From #__facileforms_elements Where form = " . intval($form_id) . " And `name` Not In ('bfFakeName','bfFakeName2','bfFakeName3','bfFakeName4','bfFakeName5','bfFakeName6') Order by `ordering`");
    jimport('joomla.version');
    $version = new JVersion();
    if(version_compare($version->getShortVersion(), '3.0', '>=')){
        $rows = $db->loadColumn();
    }else{
        $rows = $db->loadResultArray();
    }
    $out = '<script type="text/javascript">
    function insert_'.$element_target_id.'HTML(myValue) {
        var content = '.$editor->getContent($element_target_id).';
        '.$editor->setContent($element_target_id, 'content+myValue').';
    }
    </script>';
    if($rows){
        foreach($rows As $row){
            $out .= '<a href="javascript: insert_'.$element_target_id.'HTML(\'{'.$row.':label}\');void(0);">{'.$row.':label}</a><br/>';
            $out .= '<a href="javascript: insert_'.$element_target_id.'HTML(\'{'.$row.':value}\');void(0);">{'.$row.':value}</a><br/><br/>';
        }
    }
    return $out;
}

function bf_ToolTip( $tooltip, $title='', $width='', $image='tooltip.png', $text='', $href='', $link=1 )
{
	// Initialize the toolips if required
	static $init;
	if ( ! $init )
	{
		JHTML::_('behavior.tooltip');
		$init = true;
	}

	return JHTML::_('tooltip', $tooltip, $title, $image, $text, $href, $link);
}

// used if copy is disabled
function bf_copy($file1,$file2){
	$contentx =@file_get_contents($file1);
	$openedfile = @fopen($file2, "w");
	@fwrite($openedfile, $contentx);
	@fclose($openedfile);
	if ($contentx === FALSE) {
		$status=false;
	}else $status=true;
	 
	return $status;
}
    
function bf_createMail( $from='', $fromname='', $subject, $body ) {

        jimport('joomla.version');
        $version = new JVersion();
        $version = $version->getShortVersion();
    
        $_mailfrom = '';
        $_fromname = '';
        
        if(version_compare($version, '3.0', '<')){
            $_mailfrom = JFactory::getConfig()->getValue('config.mailfrom','');
            $_fromname = JFactory::getConfig()->getValue('config.fromname','');
        }else{
            $_mailfrom = JFactory::getConfig()->get('mailfrom','');
            $_fromname = JFactory::getConfig()->get('fromname','');
        }
    
	$mail = JFactory::getMailer();
        
        $mail->setSender(array($_mailfrom, trim($_fromname)));
        $mail->setSubject($subject);
        $mail->setBody($body);
        
        $mail->addReplyTo( array( $from ? $from : $_mailfrom, $fromname ? $fromname : $_fromname ) );
        
	return $mail;
}

function bf_sendNotificationBySession($session){
	
	$contents = JFactory::getSession()->get($session, array());

	if(count($contents) != 0){
		
		$from = $contents['from'];
		$fromname = $contents['fromname'];
		$recipient = $contents['recipients'];
		$subject = $contents['subject'];
		$body = $contents['body'];
		$attachment = $contents['attachment'];
		$html = $contents['isHtml'];

                if((is_array($recipient) && count($recipient) != 0) || ( !is_array($recipient) && $recipient != '' )){

                    $mail = bf_createMail($from, $fromname, $subject, $body);
                    if (is_array($recipient))
                    foreach ($recipient as $to) $mail->AddAddress($to);
                    else
                    $mail->AddAddress($recipient);

                    if ($attachment) {
                            if ( is_array($attachment) )
                            foreach ($attachment as $fname) $mail->AddAttachment($fname);
                            else
                            $mail->AddAttachment($attachment);
                    } // if

                    if (isset($html)) $mail->IsHTML($html);

                    $mail->Send();
                }
	}
	
	JFactory::getSession()->set($session, array());
}

function bf_sendNotificationByPaymentCache($formId, $recordId, $type = 'admin'){

        $contents = array();
        $sourcePath = JPATH_SITE . '/media/breezingforms/payment_cache/';
        if (@file_exists($sourcePath) && @is_readable($sourcePath) && @is_dir($sourcePath) && $handle = @opendir($sourcePath)) {
            while (false !== ($file = @readdir($handle))) {
                if($file!="." && $file!="..") {
                    $parts = explode('_', $file);
                    if(count($parts)==4) {
                        if($parts[0] == intval($formId) && $parts[1] == intval($recordId) && $parts[2] == $type) {
                            $contents = unserialize(JFile::read($sourcePath.$file));
                            JFile::delete($sourcePath.$file);
                            break;
                        }
                    }
                }
            }
            @closedir($handle);
        }

	if(count($contents) != 0){

		$from = $contents['from'];
		$fromname = $contents['fromname'];
		$recipient = $contents['recipients'];
		$subject = $contents['subject'];
		$body = $contents['body'];
		$attachment = $contents['attachment'];
		$html = $contents['isHtml'];

                if((is_array($recipient) && count($recipient) != 0) || ( !is_array($recipient) && $recipient != '' )){

                    $mail = bf_createMail($from, $fromname, $subject, $body);
                    if (is_array($recipient))
                    foreach ($recipient as $to) $mail->AddAddress($to);
                    else
                    $mail->AddAddress($recipient);

                    if ($attachment) {
                            if ( is_array($attachment) )
                            foreach ($attachment as $fname) $mail->AddAttachment($fname);
                            else
                            $mail->AddAttachment($attachment);
                    } // if

                    if (isset($html)) $mail->IsHTML($html);

                    $mail->Send();
                }
	}
}

/**
 * The name says it all
 *
 * @param string $string
 * @return boolean
 */
function bf_isUTF8($string) {
	if (is_array($string))
	{
		$enc = implode('', $string);
		return @!((ord($enc[0]) != 239) && (ord($enc[1]) != 187) && (ord($enc[2]) != 191));
	}
	else
	{
		return (utf8_encode(utf8_decode($string)) == $string);
	}
}

/**
 * The classic recursive slash remover
 *
 * @param string $value raw
 * @return string cleaned
 */
function bf_stripslashes_deep($value)
{
	if(get_magic_quotes_gpc()) {
		$value = is_array($value) ?
		array_map('bf_stripslashes_deep', $value) :
		stripslashes($value);
	}

	return $value;
}

function bf_is_email ($email, $checkDNS = false) {
	//      Check that $email is a valid address
	//              (http://tools.ietf.org/html/rfc3696)
	//              (http://tools.ietf.org/html/rfc2822)
	//              (http://tools.ietf.org/html/rfc5322#section-3.4.1)
	//              (http://tools.ietf.org/html/rfc5321#section-4.1.3)
	//              (http://tools.ietf.org/html/rfc4291#section-2.2)
	//              (http://tools.ietf.org/html/rfc1123#section-2.1)

	//      the upper limit on address lengths should normally be considered to be 256
	//              (http://www.rfc-editor.org/errata_search.php?rfc=3696)
	if (strlen($email) > 256)       return false;   //      Too long

	//      Contemporary email addresses consist of a "local part" separated from
	//      a "domain part" (a fully-qualified domain name) by an at-sign ("@").
	//              (http://tools.ietf.org/html/rfc3696#section-3)
	$index = strrpos($email,'@');

	if ($index === false)           return false;   //      No at-sign
	if ($index === 0)                       return false;   //      No local part
	if ($index > 64)                        return false;   //      Local part too long

	$localPart              = substr($email, 0, $index);
	$domain                 = substr($email, $index + 1);
	$domainLength   = strlen($domain);

	if ($domainLength === 0)        return false;   //      No domain part
	if ($domainLength > 255)        return false;   //      Domain part too long

	//      Let's check the local part for RFC compliance...
	//
	//      local-part      =       dot-atom / quoted-string / obs-local-part
	//      obs-local-part  =       word *("." word)
	//              (http://tools.ietf.org/html/rfc2822#section-3.4.1)
	if (preg_match('/^"(?:.)*"$/', $localPart) > 0) {
		$dotArray[]     = $localPart;
	} else {
		$dotArray       = explode('.', $localPart);
	}

	foreach ($dotArray as $localElement) {
		//      Period (".") may...appear, but may not be used to start or end the
		//      local part, nor may two or more consecutive periods appear.
		//              (http://tools.ietf.org/html/rfc3696#section-3)
		//
		//      A zero-length element implies a period at the beginning or end of the
		//      local part, or two periods together. Either way it's not allowed.
		if ($localElement === '')                                                                               return false;   //      Dots in wrong place

		//      Each dot-delimited component can be an atom or a quoted string
		//      (because of the obs-local-part provision)
		if (preg_match('/^"(?:.)*"$/', $localElement) > 0) {
			//      Quoted-string tests:
			//
			//      Note that since quoted-pair
			//      is allowed in a quoted-string, the quote and backslash characters may
			//      appear in a quoted-string so long as they appear as a quoted-pair.
			//              (http://tools.ietf.org/html/rfc2822#section-3.2.5)
			$groupCount     = preg_match_all('/(?:^"|"$|\\\\\\\\|\\\\")|(\\\\|")/', $localElement, $matches);
			array_multisort($matches[1], SORT_DESC);
			if ($matches[1][0] !== '')                                                                      return false;   //      Unescaped quote or backslash character inside quoted string
			if (preg_match('/^"\\\\*"$/', $localElement) > 0)                       return false;   //      "" and "\" are slipping through - note: must tidy this up
		} else {
			//      Unquoted string tests:
			//
			//      Any ASCII graphic (printing) character other than the
			//      at-sign ("@"), backslash, double quote, comma, or square brackets may
			//      appear without quoting.  If any of that list of excluded characters
			//      are to appear, they must be quoted
			//              (http://tools.ietf.org/html/rfc3696#section-3)
			//
			$stripped = '';
			//      Any excluded characters? i.e. <space>, @, [, ], \, ", <comma>
			if (preg_match('/[ @\\[\\]\\\\",]/', $localElement) > 0)
			//      Check all excluded characters are escaped
			$stripped = preg_replace('/\\\\[ @\\[\\]\\\\",]/', '', $localElement);
			if (preg_match('/[ @\\[\\]\\\\",]/', $stripped) > 0)    return false;   //      Unquoted excluded characters
		}
	}

	//      Now let's check the domain part...

	//      The domain name can also be replaced by an IP address in square brackets
	//              (http://tools.ietf.org/html/rfc3696#section-3)
	//              (http://tools.ietf.org/html/rfc5321#section-4.1.3)
	//              (http://tools.ietf.org/html/rfc4291#section-2.2)
	if (preg_match('/^\\[(.)+]$/', $domain) === 1) {
		//      It's an address-literal
		$addressLiteral = substr($domain, 1, $domainLength - 2);
		$matchesIP              = array();

		//      Extract IPv4 part from the end of the address-literal (if there is one)
		if (preg_match('/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', $addressLiteral, $matchesIP) > 0) {
			$index = strrpos($addressLiteral, $matchesIP[0]);

			if ($index === 0) {
				//      Nothing there except a valid IPv4 address, so...
				return true;
			} else {
				//      Assume it's an attempt at a mixed address (IPv6 + IPv4)
				if ($addressLiteral[$index - 1] !== ':')                        return false;   //      Character preceding IPv4 address must be ':'
				if (substr($addressLiteral, 0, 5) !== 'IPv6:')          return false;   //      RFC5321 section 4.1.3

				$IPv6 = substr($addressLiteral, 5, ($index ===7) ? 2 : $index - 6);
				$groupMax = 6;
			}
		} else {
			//      It must be an attempt at pure IPv6
			if (substr($addressLiteral, 0, 5) !== 'IPv6:')                  return false;   //      RFC5321 section 4.1.3
			$IPv6 = substr($addressLiteral, 5);
			$groupMax = 8;
		}

		$groupCount     = preg_match_all('/^[0-9a-fA-F]{0,4}|\\:[0-9a-fA-F]{0,4}|(.)/', $IPv6, $matchesIP);
		$index          = strpos($IPv6,'::');

		if ($index === false) {
			//      We need exactly the right number of groups
			if ($groupCount !== $groupMax)                                                  return false;   //      RFC5321 section 4.1.3
		} else {
			if ($index !== strrpos($IPv6,'::'))                                             return false;   //      More than one '::'
			$groupMax = ($index === 0 || $index === (strlen($IPv6) - 2)) ? $groupMax : $groupMax - 1;
			if ($groupCount > $groupMax)                                                    return false;   //      Too many IPv6 groups in address
		}

		//      Check for unmatched characters
		array_multisort($matchesIP
		[1], SORT_DESC);
		if ($matchesIP[1][0] !== '')                                                            return false;   //      Illegal characters in address

		//      It's a valid IPv6 address, so...
		return true;
	} else {
		//      It's a domain name...

		//      The syntax of a legal Internet host name was specified in RFC-952
		//      One aspect of host name syntax is hereby changed: the
		//      restriction on the first character is relaxed to allow either a
		//      letter or a digit.
		//              (http://tools.ietf.org/html/rfc1123#section-2.1)
		//
		//      NB RFC 1123 updates RFC 1035, but this is not currently apparent from reading RFC 1035.
		//
		//      Most common applications, including email and the Web, will generally not permit...escaped strings
		//              (http://tools.ietf.org/html/rfc3696#section-2)
		//
		//      Characters outside the set of alphabetic characters, digits, and hyphen MUST NOT appear in domain name
		//      labels for SMTP clients or servers
		//              (http://tools.ietf.org/html/rfc5321#section-4.1.2)
		//
		//      RFC5321 precludes the use of a trailing dot in a domain name for SMTP purposes
		//              (http://tools.ietf.org/html/rfc5321#section-4.1.2)
		$matches        = array();
		$groupCount     = preg_match_all('/(?:[0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]|[a-zA-Z])(?:\\.|$)|(.)/', $domain, $matches);
		$level          = count($matches[0]);

		if ($level == 1)                                                                                        return false;   //      Mail host can't be a TLD

		$TLD = $matches[0][$level - 1];
		if (substr($TLD, strlen($TLD) - 1, 1) === '.')                          return false;   //      TLD can't end in a dot
		if (preg_match('/^[0-9]+$/', $TLD) > 0)                                         return false;   //      TLD can't be all-numeric

		//      Check for unmatched characters
		array_multisort($matches[1], SORT_DESC);
		if ($matches[1][0] !== '')                                                                      return false;   //      Illegal characters in domain, or label longer than 63 characters

		//      Check DNS?
		if ($checkDNS && function_exists('checkdnsrr')) {
			if (!(checkdnsrr($domain, 'A') || checkdnsrr($domain, 'MX'))) {
				return false;   //      Domain doesn't actually exist
			}
		}

		//      Eliminate all other factors, and the one which remains must be the truth.
		//              (Sherlock Holmes, The Sign of Four)
		return true;
	}
}

function BFRedirect($link, $msg = null) {
 	$mainframe = JFactory::getApplication();
	$mainframe->redirect($link, $msg);
}