/**
  * Generate a MULTIPLE (many selections) View/Edit List to manage ID Selections
  *
  * @param STRING			$y_id					the HTML element ID
  * @param STRING 			$y_selected_value		selected value(s) data as ARRAY or STRING list as: '<id1>,<id2>'
  * @param ENUM				$y_mode					'form' = display form | checkboxes | 'list' = display list
  * @param ARRAY				$yarr_data				DATASET ROWS AS: ['id' => 'name', 'id2' => 'name2'] OR ['id', 'name', 'id2', 'name2']
  * @param STRING 			$y_varname				as 'frm[test][]'
  * @param ENUM				$y_draw 				list | checkboxes
  * @param YES/NO 			$y_sync_values			If Yes, sync select similar values used (curently works only for checkboxes)
  * @param INTEGER			$y_dimensions			dimensions in pixels (width or width / (list) height for '#JS-UI#' or '#JS-UI-FILTER#')
  * @param CODE				$y_custom_js			custom js code (Ex: submit on change)
  * @param SPECIAL			$y_extrastyle			Extra Style CSS | '#JS-UI#' or '#JS-UI-FILTER#'
  *
  * @return HTMLCode
  */
 public static function html_multi_select_list($y_id, $y_selected_value, $y_mode, $yarr_data, $y_varname = '', $y_draw = 'list', $y_sync_values = 'no', $y_dimensions = '300/0', $y_custom_js = '', $y_extrastyle = '#JS-UI-FILTER#')
 {
     //-- fix associative array
     $arr_type = Smart::array_type_test($yarr_data);
     if ($arr_type === 2) {
         // associative array detected
         $arr_save = (array) $yarr_data;
         $yarr_data = array();
         foreach ((array) $arr_save as $key => $val) {
             $yarr_data[] = (string) $key;
             $yarr_data[] = (string) $val;
         }
         //end foreach
         $arr_save = array();
     }
     //end if
     //--
     //-- bug fix
     if (Smart::array_size($yarr_data) > 2) {
         $use_multi_list_jq = true;
         $use_multi_list_htm = 'multiple size="8"';
     } else {
         $use_multi_list_jq = false;
         $use_multi_list_htm = 'size="1"';
     }
     //end if else
     //--
     //--
     $tmp_dimens = explode('/', trim((string) $y_dimensions));
     $the_width = (int) $tmp_dimens[0];
     $the_height = (int) $tmp_dimens[1];
     //--
     if ($the_width <= 0) {
         $the_width = 150;
     }
     //end if
     if ($the_height < 0) {
         $the_height = 0;
     }
     //end if
     //--
     //--
     $element_id = Smart::escape_html($y_id);
     //--
     //--
     $css_class = '';
     //--
     if ((string) $element_id != '' && ((string) $y_extrastyle == '#JS-UI#' || (string) $y_extrastyle == '#JS-UI-FILTER#')) {
         //--
         $use_blank_value = 'no';
         //--
         $tmp_extra_style = (string) $y_extrastyle;
         $y_extrastyle = '';
         // reset
         //--
         if ((string) $y_mode == 'form') {
             //--
             if ($the_height > 0) {
                 if ($the_height < 50) {
                     $the_height = 50;
                 }
                 //end if
                 if ($the_height > 200) {
                     $the_height = 200;
                 }
                 //end if
             } else {
                 $the_height = (int) ((Smart::array_size($yarr_data) + 1) * 20);
                 if ($the_height > 200) {
                     $the_height = 200;
                 }
                 //end if
             }
             //end if else
             //--
             if ((string) $tmp_extra_style == '#JS-UI-FILTER#') {
                 $have_filter = true;
                 $the_width += 25;
             } else {
                 $have_filter = false;
             }
             //end if else
             //--
             if ($use_multi_list_jq === false) {
                 $use_blank_value = 'yes';
                 $have_filter = false;
                 // if multi will be enforced to single because of just 2 rows or less, disable filter !
             }
             //end if
             //--
             $js = (string) SmartMarkersTemplating::render_file_template('lib/core/templates/ui-list-multi.inc.htm', ['LANG' => (string) SmartTextTranslations::getLanguage(), 'ID' => (string) $element_id, 'WIDTH' => (int) $the_width, 'HEIGHT' => (int) $the_height, 'USE-JQ' => (bool) $use_multi_list_jq, 'HAVE-FILTER' => (bool) $have_filter], 'yes');
             //--
         }
         //end if
         //--
     } else {
         //--
         $use_blank_value = 'no';
         //--
         $js = '';
         $css_class = 'class="ux-field"';
         //--
     }
     //end if else
     //--
     //--
     $out = '';
     //--
     if ((string) $y_mode == 'form') {
         //--
         if ((string) $y_draw == 'checkboxes') {
             // checkboxes
             $out .= '<input type="hidden" name="' . $y_varname . '" value="">' . "\n";
             // we need a hidden value
         } else {
             // list
             $out .= '<select name="' . $y_varname . '" id="' . $element_id . '" ' . $css_class . ' style="width:' . $the_width . 'px; ' . $y_extrastyle . '" ' . $use_multi_list_htm . ' ' . $y_custom_js . '>' . "\n";
             if ((string) $use_blank_value == 'yes') {
                 $out .= '<option value="">&nbsp;</option>' . "\n";
                 // we need a blank value to unselect
             }
             //end if
         }
         //end if else
         //--
     }
     //end if
     //--
     for ($i = 0; $i < Smart::array_size($yarr_data); $i++) {
         //--
         $i_key = $i;
         $i_val = $i + 1;
         $i = $i + 1;
         //--
         if ((string) $y_mode == 'form') {
             //--
             $tmp_el_id = 'SmartFrameworkComponents_MultiSelect_ID__' . sha1($y_varname . $yarr_data[$i_key]);
             //--
             $tmp_sel = '';
             $tmp_checked = '';
             //--
             if (is_array($y_selected_value)) {
                 //--
                 if (in_array($yarr_data[$i_key], $y_selected_value)) {
                     //--
                     $tmp_sel = ' selected';
                     $tmp_checked = ' checked';
                     //--
                 }
                 //end if
                 //--
             } else {
                 //--
                 if (SmartUnicode::str_icontains($y_selected_value, '<' . $yarr_data[$i_key] . '>')) {
                     // multiple categs as <id1>,<id2>
                     //--
                     $tmp_sel = ' selected';
                     $tmp_checked = ' checked';
                     //--
                 }
                 //end if
                 //--
             }
             //end if
             //--
             if ((string) $y_draw == 'checkboxes') {
                 // checkboxes
                 //--
                 if ((string) $y_sync_values == 'yes') {
                     $tmp_onclick = ' onClick="SmartJS_BrowserUtils.checkAll_CkBoxes(this.form.name, \'' . Smart::escape_html($tmp_el_id) . '\', this.checked);"';
                 } else {
                     $tmp_onclick = '';
                 }
                 //end if else
                 //--
                 $out .= '<input type="checkbox" name="' . $y_varname . '" id="' . Smart::escape_html($tmp_el_id) . '" value="' . Smart::escape_html($yarr_data[$i_key]) . '"' . $tmp_checked . $tmp_onclick . '>';
                 $out .= ' &nbsp; ' . Smart::escape_html($yarr_data[$i_val]) . '<br>';
                 //--
             } else {
                 // list
                 //--
                 if ((string) $yarr_data[$i_key] == '#OPTGROUP#') {
                     $out .= '<optgroup label="' . Smart::escape_html($yarr_data[$i_val]) . '">' . "\n";
                     // the optgroup
                 } else {
                     $out .= '<option value="' . Smart::escape_html($yarr_data[$i_key]) . '"' . $tmp_sel . '>&nbsp;' . Smart::escape_html($yarr_data[$i_val]) . '</option>' . "\n";
                 }
                 //end if else
                 //--
             }
             //end if else
             //--
         } else {
             //--
             if (is_array($y_selected_value)) {
                 //--
                 if (in_array($yarr_data[$i_key], $y_selected_value)) {
                     //--
                     $out .= '&middot;&nbsp;' . Smart::escape_html($yarr_data[$i_val]) . '<br>' . "\n";
                     //--
                 }
                 //end if
                 //--
             } else {
                 //--
                 if (SmartUnicode::str_icontains($y_selected_value, '<' . $yarr_data[$i_key] . '>')) {
                     //-- multiple categs as <id1>,<id2>
                     $out .= '&middot;&nbsp;' . Smart::escape_html($yarr_data[$i_val]) . '<br>' . "\n";
                     //--
                 }
                 // end if
                 //--
             }
             //end if else
             //--
         }
         //end if else
         //--
     }
     //end for
     //--
     if ((string) $y_mode == 'form') {
         //--
         if ((string) $y_draw == 'checkboxes') {
             // checkboxes
             $out .= '<br>' . "\n";
         } else {
             // list
             $out .= '</select>' . "\n";
             $out .= $js . "\n";
         }
         //end if else
         //--
     }
     //end if
     //--
     //--
     return $out;
     //--
 }
 public function connect($server, $port = 110, $sslversion = '')
 {
     //-- inits
     $this->socket = false;
     $this->apop_banner = '';
     //--
     //-- checks
     $server = trim($server);
     if (strlen($server) <= 0 or strlen($server) > 255) {
         $this->error = '[ERR] Invalid Server to Connect ! [' . $server . ']';
         return 0;
     }
     //end if
     //--
     $port = (int) $port;
     if ($port <= 0 or $port > 65535) {
         $this->error = '[ERR] Invalid Port to Connect ! [' . $port . ']';
         return 0;
     }
     //end if
     //--
     //--
     $protocol = '';
     //--
     if (strlen($sslversion) > 0) {
         //--
         if (!function_exists('openssl_open')) {
             $this->error = '[ERR] PHP OpenSSL Extension is required to perform SSL requests !';
             return 0;
         }
         //end if
         //--
         switch (strtolower($sslversion)) {
             case 'ssl':
                 $protocol = 'ssl://';
                 break;
             case 'sslv3':
                 $protocol = 'sslv3://';
                 break;
             case 'tls':
             default:
                 $protocol = 'tls://';
         }
         //end switch
         //--
     }
     //end if else
     //--
     //--
     if ($this->debug) {
         $this->log .= '[INF] Connecting to Mail Server: ' . $protocol . $server . ':' . $port . "\n";
     }
     //end if
     //--
     //--
     //$sock = @fsockopen($protocol.$server, $port, $errno, $errstr, $this->timeout);
     $stream_context = @stream_context_create();
     if ((string) $protocol != '') {
         if (defined('SMART_FRAMEWORK_SSL_CA_PATH')) {
             if ((string) SMART_FRAMEWORK_SSL_CA_PATH != '') {
                 @stream_context_set_option($stream_context, 'ssl', 'capath', Smart::real_path((string) SMART_FRAMEWORK_SSL_CA_PATH));
             }
             //end if
         }
         //end if
         @stream_context_set_option($stream_context, 'ssl', 'ciphers', (string) SMART_FRAMEWORK_SSL_CIPHERS);
         // allow only high ciphers
         @stream_context_set_option($stream_context, 'ssl', 'verify_host', (bool) SMART_FRAMEWORK_SSL_VFY_HOST);
         // allways must be set to true !
         @stream_context_set_option($stream_context, 'ssl', 'verify_peer', (bool) SMART_FRAMEWORK_SSL_VFY_PEER);
         // this may fail with some CAs
         @stream_context_set_option($stream_context, 'ssl', 'verify_peer_name', (bool) SMART_FRAMEWORK_SSL_VFY_PEER_NAME);
         // allow also wildcard names *
         @stream_context_set_option($stream_context, 'ssl', 'allow_self_signed', (bool) SMART_FRAMEWORK_SSL_ALLOW_SELF_SIGNED);
         // must allow self-signed certificates but verified above
         @stream_context_set_option($stream_context, 'ssl', 'disable_compression', (bool) SMART_FRAMEWORK_SSL_DISABLE_COMPRESS);
         // help mitigate the CRIME attack vector
     }
     //end if else
     $sock = @stream_socket_client($protocol . $server . ':' . $port, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $stream_context);
     //--
     if (!is_resource($sock)) {
         $this->error = '[ERR] Could not open connection. Error: ' . $errno . ' :: ' . $errstr;
         return 0;
     }
     //end if
     //--
     $this->socket = $sock;
     unset($sock);
     //--
     @stream_set_timeout($this->socket, (int) SMART_FRAMEWORK_NETSOCKET_TIMEOUT);
     if ($this->debug) {
         $this->log .= '[INF] Set Socket Stream TimeOut to: ' . SMART_FRAMEWORK_NETSOCKET_TIMEOUT . "\n";
     }
     //end if
     //--
     //-- If mode is 0, the given stream will be switched to non-blocking mode, and if 1, it will be switched to blocking mode. This affects calls like fgets() and fread()  that read from the stream. In non-blocking mode an fgets() call will always return right away while in blocking mode it will wait for data to become available on the stream.
     @socket_set_blocking($this->socket, 1);
     // set to blocking mode
     //--
     //-- avoid connect normally if SSL/TLS was explicit required
     $chk_crypto = (array) @stream_get_meta_data($this->socket);
     if ((string) $protocol != '') {
         if (!SmartUnicode::str_icontains($chk_crypto['stream_type'], '/ssl')) {
             // will return something like: tcp_socket/ssl
             //--
             $this->error = '[ERR] Connection CRYPTO CHECK Failed ...' . "\n";
             //--
             @socket_set_blocking($this->socket, 0);
             @fclose($this->socket);
             $this->socket = false;
             //--
             return 0;
             //--
         }
         //end if
     }
     //end if
     //--
     //--
     $reply = @fgets($this->socket, $this->buffer);
     $reply = $this->strip_clf($reply);
     $test = $this->is_ok($reply);
     //--
     if ((string) $test != 'ok') {
         //--
         $this->error = '[ERR] Server Reply is NOT OK // ' . $test . ' // ' . $reply;
         //--
         @socket_set_blocking($this->socket, 0);
         @fclose($this->socket);
         $this->socket = false;
         //--
         return 0;
         //--
     }
     //end if
     //--
     if ($this->debug) {
         $this->log .= '[REPLY] \'' . $reply . '\'' . "\n";
     }
     //end if
     //--
     //-- apop banner
     $this->apop_banner = $this->parse_banner($reply);
     //--
     //--
     return 1;
     //--
 }
    public static function test_strings()
    {
        //--
        $unicode_text = '"Unicode78źź:ăĂîÎâÂșȘțȚşŞţŢグッド';
        //--
        $idn_domain_unicode = 'jösefsson.tßst123.org';
        $idn_domain_iso = 'xn--jsefsson-n4a.xn--tst123-bta.org';
        $idn_email_unicode = 'räksmörgås@jösefsson.tßst123.org';
        $idn_email_iso = '*****@*****.**';
        //--
        //--
        $err = '';
        //--
        //--
        $tests[] = '##### Unicode STRING / TESTS: #####';
        //--
        //--
        $regex_positive = '/^[\\w"\\:\\?]+$/';
        $regex_negative = '/[^\\w"\\:\\?]/';
        //--
        //--
        if (defined('SMART_FRAMEWORK_SECURITY_FILTER_INPUT')) {
            if ((string) SMART_FRAMEWORK_SECURITY_FILTER_INPUT != '') {
                if ((string) $err == '') {
                    $the_test = 'Smart.Framework Security Input Filter Regex - test over a full Unicode String';
                    $tests[] = $the_test;
                    if (preg_match((string) SMART_FRAMEWORK_SECURITY_FILTER_INPUT, 'Platform クラウドアプリケーションプラットフォーム \'áâãäåāăąÁÂÃÄÅĀĂĄćĉčçĆĈČÇďĎèéêëēĕėěęÈÉÊËĒĔĖĚĘĝģĜĢĥħĤĦìíîïĩīĭȉȋįÌÍÎÏĨĪĬȈȊĮijĵIJĴķĶĺļľłĹĻĽŁñńņňÑŃŅŇòóôõöōŏőøœÒÓÔÕÖŌŎŐØŒŕŗřŔŖŘșşšśŝßȘŞŠŚŜțţťȚŢŤùúûüũūŭůűųÙÚÛÜŨŪŬŮŰŲŵŴẏỳŷÿýẎỲŶŸÝźżžŹŻŽ " <p></p> ? & * ^ $ @ ! ` ~ % () [] {} | \\ / + - _ : ; , . #\'0.51085600 1454529112#' . "\r\n\t" . '`~@#$%^&*()-_=+[{]}|;:"<>,.?/\\')) {
                        $err = 'ERROR: ' . $the_test . ' FAILED ...';
                    }
                    //end if
                }
                //end if
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Unicode Regex Test Positive';
            $tests[] = $the_test;
            if (!preg_match((string) $regex_positive . 'u', (string) $unicode_text)) {
                $err = 'ERROR: ' . $the_test . ' FAILED (1) ...';
            } elseif (preg_match((string) $regex_positive, (string) $unicode_text)) {
                $err = 'ERROR: ' . $the_test . ' FAILED (2) ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Unicode Regex Test Negative';
            $tests[] = $the_test;
            if (preg_match((string) $regex_negative . 'u', (string) $unicode_text)) {
                $err = 'ERROR: ' . $the_test . ' FAILED (1) ...';
            } elseif (!preg_match((string) $regex_negative, (string) $unicode_text)) {
                $err = 'ERROR: ' . $the_test . ' FAILED (2) ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Deaccented ISO Regex Test Positive';
            $tests[] = $the_test;
            if (!preg_match((string) $regex_positive, (string) SmartUnicode::deaccent_str($unicode_text))) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Deaccented ISO Regex Test Negative';
            $tests[] = $the_test;
            if (preg_match((string) $regex_negative, (string) SmartUnicode::deaccent_str($unicode_text))) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode Strlen Test';
            $tests[] = $the_test;
            if (SmartUnicode::str_len($unicode_text) !== 30) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            // this tests also SmartUnicode::str_ipos
            $the_test = 'Unicode Find Substring (Case Insensitive), Positive';
            $tests[] = $the_test;
            if (SmartUnicode::str_icontains($unicode_text, 'șș') !== true) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            // this tests also SmartUnicode::str_ipos
            $the_test = 'Unicode Find Substring (Case Insensitive), Negative';
            $tests[] = $the_test;
            if (SmartUnicode::str_icontains($unicode_text, 'șş') !== false) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            // this tests also SmartUnicode::str_pos
            $the_test = 'Unicode Find Substring (Case Sensitive), Positive';
            $tests[] = $the_test;
            if (SmartUnicode::str_contains($unicode_text, 'țȚ') !== true) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            // this tests also SmartUnicode::str_pos
            $the_test = 'Unicode Find Substring (Case Sensitive), Negative';
            $tests[] = $the_test;
            if (SmartUnicode::str_contains($unicode_text, 'țŢ') !== false) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode Find Substring (Case Insensitive), Reverse';
            $tests[] = $the_test;
            if (SmartUnicode::str_ripos($unicode_text, 'ţţグ') === false) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Unicode Find Substring (Case Sensitive), Reverse';
            $tests[] = $the_test;
            if (SmartUnicode::str_rpos($unicode_text, 'ţŢグ') === false) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode Return Substring (Case Insensitive)';
            $tests[] = $the_test;
            if (SmartUnicode::stri_str($unicode_text, 'âȘșȚ') !== 'ÂșȘțȚşŞţŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Unicode Return Substring (Case Sensitive)';
            $tests[] = $the_test;
            if (SmartUnicode::str_str($unicode_text, 'ÂșȘț') !== 'ÂșȘțȚşŞţŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode String to LowerCase';
            $tests[] = $the_test;
            if (SmartUnicode::str_tolower($unicode_text) !== '"unicode78źź:ăăîîââșșțțşşţţグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Unicode String to UpperCase';
            $tests[] = $the_test;
            if (SmartUnicode::str_toupper($unicode_text) !== '"UNICODE78ŹŹ:ĂĂÎÎÂÂȘȘȚȚŞŞŢŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode SubString function (without last param)';
            $tests[] = $the_test;
            if (SmartUnicode::sub_str($unicode_text, 25) !== 'ţŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'Unicode SubString function (with last param)';
            $tests[] = $the_test;
            if (SmartUnicode::sub_str($unicode_text, 25, 3) !== 'ţŢグ') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode SubString Count function';
            $tests[] = $the_test;
            if (SmartUnicode::substr_count($unicode_text, 'ţ') !== 1) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Unicode String Replace with Limit (Case Sensitive)';
            $tests[] = $the_test;
            if (SmartUnicode::str_limit_replace('ź', '@', $unicode_text, 1) !== '"Unicode78@ź:ăĂîÎâÂșȘțȚşŞţŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'String Replace without Limit (Case Sensitive)';
            $tests[] = $the_test;
            if (str_replace('ź', '@', $unicode_text) !== '"Unicode78@@:ăĂîÎâÂșȘțȚşŞţŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            /* This test fails if the replacements accented characters are different case than one find in string (upper/lower) ... */
            $the_test = 'String Replace without Limit (Case Insensitive) *** Only with unaccented replacements !!';
            $tests[] = $the_test;
            if (str_ireplace('E7', '@', $unicode_text) !== '"Unicod@8źź:ăĂîÎâÂșȘțȚşŞţŢグッド') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Deaccent String';
            $tests[] = $the_test;
            if (SmartUnicode::deaccent_str($unicode_text) !== '"Unicode78zz:aAiIaAsStTsStT???') {
                $err = 'ERROR: ' . $the_test . ' FAILED ...';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'YAML Unicode Test: Compose from Array / Parse from YAML';
            $tests[] = $the_test;
            $test_arr = array('@test' => 'Testing weird key characters', 'line1' => 'Some ISO-8859-1 String: @ # $ % ^ & * (\') _ - + = { [ ] } ; < ,. > / ? \\ |', 'line2' => 'Unicode (long) String: ' . $unicode_text . ' ' . SmartUnicode::str_toupper($unicode_text) . ' ' . $unicode_text . ' ' . SmartUnicode::str_tolower($unicode_text) . ' ' . $unicode_text . ' ' . SmartUnicode::deaccent_str($unicode_text) . ' ' . $unicode_text, $unicode_text => 'Unicode as Key', 'line3' => ['A' => 'b', 100, 'Thousand'], 'line4' => [1, 0.2, 3.0001], 'line5' => date('Y-m-d H:i:s'));
            $test_yaml = (string) '# start YAML (to test also comments)' . "\n" . (new SmartYamlConverter())->compose($test_arr) . "\n" . '# end YAML';
            $test_parr = (new SmartYamlConverter())->parse($test_yaml);
            if ($test_arr !== $test_parr) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' #ORIGINAL Array [' . print_r($test_arr, 1) . ']' . "\n\n" . '#YAML Array (from YAML String): ' . print_r($test_parr, 1) . "\n\n" . '#YAML String (from ORIGINAL Array): ' . "\n" . $test_yaml;
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'XML Unicode Test: Compose from Array / Parse from XML';
            $tests[] = $the_test;
            $test_arr = array('TEST' => 'Testing weird key characters', 'line1' => 'Some ISO-8859-1 String: @ # $ % ^ & * (\') _ - + = { [ ] } ; < ,. > / ? \\ |', 'line2' => 'Unicode (long) String: ' . $unicode_text . ' ' . SmartUnicode::str_toupper($unicode_text) . ' ' . $unicode_text . ' ' . SmartUnicode::str_tolower($unicode_text) . ' ' . $unicode_text . ' ' . SmartUnicode::deaccent_str($unicode_text) . ' ' . $unicode_text, 'line3' => ['A' => 'b', 'c' => 'D'], 'line4' => '', 'line5' => date('Y-m-d H:i:s'));
            $test_xml = (string) (new SmartXmlComposer())->transform($test_arr);
            $test_parr = (new SmartXmlParser())->transform($test_xml);
            if ($test_arr !== $test_parr) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' #ORIGINAL Array [' . print_r($test_arr, 1) . ']' . "\n\n" . '#XML Array (from XML String): ' . print_r($test_parr, 1) . "\n\n" . '#XML String (from ORIGINAL Array): ' . "\n" . $test_xml;
            }
            //end if
        }
        //end if
        //--
        $the_random_unicode_text = sha1($unicode_text . Smart::random_number(1000, 9999)) . '-' . $unicode_text . " \r\n\t" . '-' . Smart::uuid_10_num() . '-' . Smart::uuid_10_str() . '-' . Smart::uuid_10_seq();
        //--
        if ((string) $err == '') {
            $the_test = 'Data: Archive / Unarchive';
            $tests[] = $the_test;
            if (SmartUtils::data_unarchive(SmartUtils::data_archive($the_random_unicode_text)) !== (string) $the_random_unicode_text) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' [' . $the_random_unicode_text . ']';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'Cache: Archive / Unarchive';
            $tests[] = $the_test;
            if (SmartUtils::cache_variable_unarchive(SmartUtils::cache_variable_archive($the_random_unicode_text)) !== (string) $the_random_unicode_text) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' [' . $the_random_unicode_text . ']';
            }
            //end if
        }
        //end if
        //--
        //--
        if ((string) $err == '') {
            $the_test = 'IDN: Domain Punycode Encode UTF-8 to ISO';
            $tests[] = $the_test;
            if ((string) (new SmartPunycode())->encode($idn_domain_unicode) != (string) $idn_domain_iso) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' [' . $idn_domain_unicode . ' -> ' . $idn_domain_iso . ']';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'IDN: Domain Punycode Decode ISO to UTF-8';
            $tests[] = $the_test;
            if ((string) (new SmartPunycode())->decode($idn_domain_iso) != (string) $idn_domain_unicode) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' [' . $idn_domain_iso . ' -> ' . $idn_domain_unicode . ']';
            }
            //end if
        }
        //end if
        //--
        if ((string) $err == '') {
            $the_test = 'IDN: Email Punycode Encode UTF-8 to ISO';
            $tests[] = $the_test;
            if ((string) (new SmartPunycode())->encode($idn_email_unicode) != (string) $idn_email_iso) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' [' . $idn_email_unicode . ' -> ' . $idn_email_iso . ']';
            }
            //end if
        }
        //end if
        if ((string) $err == '') {
            $the_test = 'IDN: Email Punycode Decode ISO to UTF-8';
            $tests[] = $the_test;
            if ((string) (new SmartPunycode())->decode($idn_email_iso) != (string) $idn_email_unicode) {
                $err = 'ERROR: ' . $the_test . ' FAILED ...' . ' [' . $idn_email_iso . ' -> ' . $idn_email_unicode . ']';
            }
            //end if
        }
        //end if
        //--
        //-- regex positive tests
        $arr_regex = ['number-integer' => [0, '75', '-101'], 'number-decimal' => [0, '0.0', '0.1', '75', '75.0', '75.1', '-555', '-555.0', '-555.1'], 'number-list-integer' => '1;2;30', 'number-list-decimal' => '1.0;2;30.44', 'url' => ['https://192.168.1.0', 'http://localhost', 'https://www.dom.ext', 'http://dom.ext/path?a=b&c=d%20#s'], 'domain' => ['domain.com', 'sdom.domain.org'], 'email' => ['root@localhost', '*****@*****.**', '*****@*****.**'], 'fax' => ['~+99-(0)999-123.456.78~'], 'macaddr' => ['00:0A:95:9d:68:16', '00-0a-95-9D-68-16'], 'ipv4' => ['192.168.0.1', '169.254.1.0', '1.0.0.1'], 'ipv6' => ['::1', '0000:0000:0000:0000:0000:0000:0000:0001', '2001:0db8:0000:0000:0000:ff00:0042:8329', '2001:dB8::2:1', '2001:db8::1', '3731:54:65fe:2::a7']];
        //--
        foreach ((array) $arr_regex as $key => $val) {
            //--
            if (is_array($val)) {
                for ($i = 0; $i < Smart::array_size($val); $i++) {
                    $the_test = 'Regex Validate Positive (#' . $i . '): ' . $key . ' [' . $val[$i] . ']';
                    $tests[] = $the_test;
                    if (SmartValidator::validate_string($val[$i], $key) !== true) {
                        $err = 'ERROR: ' . $the_test . ' FAILED ...';
                        break;
                    }
                    //end if
                    if (stripos((string) $key, 'number-') === 0 and stripos((string) $key, 'number-list-') === false) {
                        $the_test = 'Regex Validate Numeric Positive (#' . $i . '): ' . $key . ' [' . $val[$i] . ']';
                        $tests[] = $the_test;
                        if (SmartValidator::validate_numeric_integer_or_decimal_values($val[$i], $key) !== true) {
                            $err = 'ERROR: ' . $the_test . ' FAILED ...';
                            break;
                        }
                        //end if
                    }
                    //end if
                }
                //end for
            } else {
                $the_test = 'Regex Validate Positive: ' . $key . ' [' . $val . ']';
                $tests[] = $the_test;
                if (SmartValidator::validate_string($val, $key) !== true) {
                    $err = 'ERROR: ' . $the_test . ' FAILED ...';
                }
                //end if
                if (stripos((string) $key, 'number-') === 0 and stripos((string) $key, 'number-list-') === false) {
                    $the_test = 'Regex Validate Numeric Positive: ' . $key . ' [' . $val . ']';
                    $tests[] = $the_test;
                    if (SmartValidator::validate_numeric_integer_or_decimal_values($val, $key) !== true) {
                        $err = 'ERROR: ' . $the_test . ' FAILED ...';
                    }
                    //end if
                }
                //end if
            }
            //end if else
            //--
            if ((string) $err != '') {
                break;
            }
            //end if
            //--
        }
        //end foreach
        //--
        //-- regex negative tests
        $arr_regex = ['number-integer' => ['', '.', 'a9', '7B', '-9 ', ' -7'], 'number-decimal' => ['', '.0', '.1', '-.10', ' -7', '-9.0 '], 'number-list-integer' => '1;2.3;30', 'number-list-decimal' => '1.0;2;30.44a', 'url' => ['http:://192.168.1.0', 'https://local host', 'http:/www.dom.ext', 'https:dom.ext/path?a=b&c=d%20#s'], 'domain' => ['doMain.com', 's dom.domain.org', '.dom.ext', 'dom..ext', 'localhost', 'loc', 'dom.ext.'], 'email' => ['rooT@localhost', 'root@local host.loc', 'sometest-name.extra@do_m.ext'], 'fax' => ['~ +99-(0)999-123.456.78 ~'], 'macaddr' => ['00:0A:95:9z:68:16', '00-0Z-95-9D-68-16'], 'ipv4' => ['192.168.0.', '169..1.0', '1.0.1'], 'ipv6' => ['::x', '00z0:0000:0000:0000:0000:0000:0000:0001', '2001:0dx8:0000:0000:0000:ff00:0042:8329', '2001:WB8::2:1', '2001:@db8::1', '3731:54:65Qe:2::a7']];
        //--
        foreach ((array) $arr_regex as $key => $val) {
            //--
            if (is_array($val)) {
                for ($i = 0; $i < Smart::array_size($val); $i++) {
                    $the_test = 'Regex Validate Negative (#' . $i . '): ' . $key . ' [' . $val[$i] . ']';
                    $tests[] = $the_test;
                    if (SmartValidator::validate_string($val[$i], $key) === true) {
                        $err = 'ERROR: ' . $the_test . ' FAILED ...';
                        break;
                    }
                    //end if
                }
                //end for
            } else {
                $the_test = 'Regex Validate Negative: ' . $key . ' [' . $val . ']';
                $tests[] = $the_test;
                if (SmartValidator::validate_string($val, $key) === true) {
                    $err = 'ERROR: ' . $the_test . ' FAILED ...';
                }
                //end if
            }
            //end if else
            //--
            if ((string) $err != '') {
                break;
            }
            //end if
            //--
        }
        //end foreach
        //--
        //--
        $endtest = '##### END TESTS ... #####';
        //--
        //--
        if ((string) $err == '') {
            $img_sign = 'lib/core/img/sign_info.png';
            $img_check = 'lib/core/img/q_completed.png';
            $text_main = Smart::escape_js('<span style="color:#83B953;">Good ... Perfect &nbsp;&nbsp;&nbsp; :: &nbsp;&nbsp;&nbsp; グッド ... パーフェクト</span>');
            $text_info = Smart::escape_js('<h2><span style="color:#83B953;">All</span> the SmartFramework Unicode String <span style="color:#83B953;">Tests PASSED on PHP</span><hr></h2><span style="font-size:14px;">' . Smart::nl_2_br(Smart::escape_html(implode("\n" . '* ', $tests) . "\n" . $endtest)) . '</span>');
        } else {
            $img_sign = 'lib/core/img/sign_error.png';
            $img_check = 'lib/core/img/q_warning.png';
            $text_main = Smart::escape_js('<span style="color:#FF5500;">An ERROR occured ... &nbsp;&nbsp;&nbsp; :: &nbsp;&nbsp;&nbsp; エラーが発生しました ...</span>');
            $text_info = Smart::escape_js('<h2><span style="color:#FF5500;">A test FAILED</span> when testing Unicode String Tests.<span style="color:#FF5500;"><hr>FAILED Test Details</span>:</h2><br><h3>' . Smart::escape_html($tests[Smart::array_size($tests) - 1]) . '</h3><br><span style="font-size:14px;"><pre>' . Smart::escape_html($err) . '</pre></span>');
        }
        //end if else
        //--
        //--
        $html = <<<HTML
<h1>SmartFramework Unicode Strings Tests: DONE ...</h1>
<script type="text/javascript">
\tSmartJS_BrowserUtils.alert_Dialog(
\t\t'<img src="{$img_sign}" align="right"><h1>{$text_main}</h1><hr><span style="color:#333333;"><img src="{$img_check}" align="right">{$text_info}<br>',
\t\t'',
\t\t'Unicode String Test Suite for SmartFramework: PHP',
\t\t'725',
\t\t'425'
\t);
</script>
HTML;
        //--
        //--
        return $html;
        //--
    }
 public function connect($helo, $server, $port = 25, $sslversion = '')
 {
     //-- inits
     $this->socket = false;
     //--
     //-- checks
     $helo = trim((string) $helo);
     $server = trim((string) $server);
     if (strlen($server) <= 0 or strlen($server) > 255) {
         $this->error = '[ERR] Invalid Server to Connect ! [' . $server . ']';
         return 0;
     }
     //end if
     //--
     $port = (int) $port;
     if ($port <= 0 or $port > 65535) {
         $this->error = '[ERR] Invalid Port to Connect ! [' . $port . ']';
         return 0;
     }
     //end if
     //--
     //--
     $protocol = '';
     $start_tls = false;
     //--
     if (strlen($sslversion) > 0) {
         //--
         if (!function_exists('openssl_open')) {
             $this->error = '[ERR] PHP OpenSSL Extension is required to perform SSL requests !';
             return 0;
         }
         //end if
         //--
         switch (strtolower($sslversion)) {
             case 'starttls':
                 $start_tls = true;
                 $protocol = '';
                 // reset because will connect in a different way
                 break;
             case 'ssl':
                 $protocol = 'ssl://';
                 break;
             case 'sslv3':
                 $protocol = 'sslv3://';
                 break;
             case 'tls':
             default:
                 $protocol = 'tls://';
         }
         //end switch
         //--
     }
     //end if else
     //--
     //--
     if ($this->debug) {
         $this->log .= '[INF] Connecting to Mail Server: ' . $protocol . $server . ':' . $port . "\n";
     }
     //end if
     //--
     //--
     //$sock = @fsockopen($protocol.$server, $port, $errno, $errstr, $this->timeout);
     $stream_context = @stream_context_create();
     if ((string) $protocol != '' or $start_tls === true) {
         if (defined('SMART_FRAMEWORK_SSL_CA_PATH')) {
             if ((string) SMART_FRAMEWORK_SSL_CA_PATH != '') {
                 @stream_context_set_option($stream_context, 'ssl', 'capath', Smart::real_path((string) SMART_FRAMEWORK_SSL_CA_PATH));
             }
             //end if
         }
         //end if
         @stream_context_set_option($stream_context, 'ssl', 'ciphers', (string) SMART_FRAMEWORK_SSL_CIPHERS);
         // allow only high ciphers
         @stream_context_set_option($stream_context, 'ssl', 'verify_host', (bool) SMART_FRAMEWORK_SSL_VFY_HOST);
         // allways must be set to true !
         @stream_context_set_option($stream_context, 'ssl', 'verify_peer', (bool) SMART_FRAMEWORK_SSL_VFY_PEER);
         // this may fail with some CAs
         @stream_context_set_option($stream_context, 'ssl', 'verify_peer_name', (bool) SMART_FRAMEWORK_SSL_VFY_PEER_NAME);
         // allow also wildcard names *
         @stream_context_set_option($stream_context, 'ssl', 'allow_self_signed', (bool) SMART_FRAMEWORK_SSL_ALLOW_SELF_SIGNED);
         // must allow self-signed certificates but verified above
         @stream_context_set_option($stream_context, 'ssl', 'disable_compression', (bool) SMART_FRAMEWORK_SSL_DISABLE_COMPRESS);
         // help mitigate the CRIME attack vector
     }
     //end if else
     $sock = @stream_socket_client($protocol . $server . ':' . $port, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $stream_context);
     //--
     if (!is_resource($sock)) {
         $this->error = '[ERR] Could not open connection. Error: ' . $errno . ' :: ' . $errstr;
         return 0;
     }
     //end if
     //--
     $this->socket = $sock;
     unset($sock);
     //--
     @stream_set_timeout($this->socket, (int) SMART_FRAMEWORK_NETSOCKET_TIMEOUT);
     if ($this->debug) {
         $this->log .= '[INF] Set Socket Stream TimeOut to: ' . SMART_FRAMEWORK_NETSOCKET_TIMEOUT . "\n";
     }
     //end if
     //--
     //--
     $reply = $this->retry_data();
     if (strlen($this->error) > 0) {
         //--
         @fclose($this->socket);
         $this->socket = false;
         //--
         return 0;
         //--
     }
     //end if
     if ($this->debug) {
         $this->log .= '[REPLY] \'' . $reply . '\'' . "\n";
     }
     //end if
     //--
     $test = $this->answer_code($reply);
     if ((string) $test != '220') {
         //--
         $this->error = '[ERR] Server Reply is NOT OK // ' . $test . ' // ' . $reply;
         //--
         @fclose($this->socket);
         $this->socket = false;
         //--
         return 0;
         //--
     }
     //end if
     //--
     //--
     if (!$this->hello($helo)) {
         //--
         $this->error = '[ERR] HELLO Command Failed // ' . $helo;
         //--
         @fclose($this->socket);
         $this->socket = false;
         //--
         return 0;
         //--
     }
     //end if
     //--
     //--
     if ($start_tls === true) {
         //--
         if ($this->starttls($stream_context) != '1') {
             //--
             if ((string) $this->error == '') {
                 $this->error = '[ERR] Connection CRYPTO ENABLE Failed ...';
             }
             //end if
             //--
             @fclose($this->socket);
             $this->socket = false;
             //--
             return 0;
             // error message comes from above
             //--
         }
         //end if
         //-- BugFix: Xmail fails after STARTTLS without sending again the HELO as 503 BAD Sequence of commands
         if (!$this->hello($helo)) {
             //--
             $this->error = '[ERR] HELLO Command Failed // ' . $helo;
             //--
             @fclose($this->socket);
             $this->socket = false;
             //--
             return 0;
             //--
         }
         //end if
         //--
     }
     //end if
     //--
     //--
     $chk_crypto = (array) @stream_get_meta_data($this->socket);
     if ((string) $protocol != '' or $start_tls === true) {
         // avoid connect normally if SSL/TLS was explicit required
         if (!SmartUnicode::str_icontains($chk_crypto['stream_type'], '/ssl')) {
             // will return something like: tcp_socket/ssl
             //--
             $this->error = '[ERR] Connection CRYPTO CHECK Failed ...';
             //--
             @fclose($this->socket);
             $this->socket = false;
             //--
             return 0;
             //--
         }
         //end if
     }
     //end if
     //--
     //--
     return 1;
     //--
 }