private function send_request($url, $user = '', $pwd = '', $method = 'GET', $ssl_version = '')
 {
     //--
     $this->method = (string) strtoupper(trim((string) $method));
     //--
     //--
     $this->connect_timeout = (int) $this->connect_timeout;
     if ($this->connect_timeout < 1) {
         $this->connect_timeout = 1;
     }
     //end if
     if ($this->connect_timeout > 120) {
         $this->connect_timeout = 120;
     }
     //end if
     //--
     //-- log action
     if ($this->debug) {
         $this->log .= '[INF] Get From URL :: is starting ...' . "\n";
     }
     //end if
     //--
     //-- separations
     $this->url_parts = (array) Smart::separe_url_parts($url);
     $protocol = (string) $this->url_parts['protocol'];
     $server = (string) $this->url_parts['server'];
     $port = (string) $this->url_parts['port'];
     $path = (string) $this->url_parts['path'];
     //--
     if ($this->debug) {
         $this->log .= '[INF] Analize of the URL: ' . @print_r($this->url_parts, 1) . "\n";
     }
     //end if
     //--
     //--
     if ((string) $server == '') {
         if ($this->debug) {
             $this->log .= '[ERR] Invalid Server to Browse' . "\n";
         }
         //end if
         Smart::log_warning('LibHTTP // GetFromURL () // Invalid (empty) Server to Browse ...');
         return 0;
     }
     //end if
     //--
     //--
     $browser_protocol = '';
     //--
     if ((string) $protocol == 'https://') {
         //--
         switch (strtolower((string) $ssl_version)) {
             case 'ssl':
                 $browser_protocol = 'ssl://';
                 break;
             case 'sslv3':
                 $browser_protocol = 'sslv3://';
                 break;
             case 'tls':
             default:
                 $browser_protocol = 'tls://';
         }
         //end switch
         //--
         if (!function_exists('openssl_open')) {
             if ($this->debug) {
                 $this->log .= '[ERR] PHP OpenSSL Extension is required to perform SSL requests' . "\n";
             }
             //end if
             Smart::log_warning('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // PHP OpenSSL Extension not installed ...');
             return 0;
         }
         //end if
         //--
     }
     //end if else
     //--
     //--
     $have_cookies = false;
     if (is_array($this->cookies)) {
         if (count($this->cookies) > 0) {
             $have_cookies = true;
         }
         //end if
     }
     //end if
     //--
     $have_post_vars = false;
     if ((string) $this->poststring != '') {
         $have_post_vars = true;
     } elseif (is_array($this->postvars)) {
         if (count($this->postvars) > 0) {
             $have_post_vars = true;
         }
         //end if
     }
     //end if
     //--
     //-- navigate
     if ($this->debug) {
         $this->log .= 'Opening HTTP(S) Browser Connection to: ' . $protocol . $server . ':' . $port . $path . ' using socket protocol: [' . $browser_protocol . ']' . "\n";
         $this->log .= '[INF] HTTP Protocol: ' . $this->protocol . "\n";
         $this->log .= '[INF] Connection TimeOut: ' . $this->connect_timeout . "\n";
     }
     //end if
     //--
     $stream_context = @stream_context_create();
     if ((string) $browser_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
     $this->socket = @stream_socket_client($browser_protocol . $server . ':' . $port, $errno, $errstr, $this->connect_timeout, STREAM_CLIENT_CONNECT, $stream_context);
     //--
     if (!is_resource($this->socket)) {
         if ($this->debug) {
             $this->log .= '[ERR] Could not open connection. Error : ' . $errno . ': ' . $errstr . "\n";
             Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Could not open connection. Error : ' . $errno . ': ' . $errstr . ' #');
         }
         //end if
         return 0;
     }
     //end if
     //--
     if ($this->debug) {
         $this->log .= '[INF] Socket Resource ID: ' . $this->socket . "\n";
     }
     //end if
     //--
     @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
     //--
     //-- avoid connect normally if SSL/TLS was explicit required
     $chk_crypto = (array) @stream_get_meta_data($this->socket);
     if ((string) $browser_protocol != '') {
         if (stripos($chk_crypto['stream_type'], '/ssl') === false) {
             // will return something like: tcp_socket/ssl
             if ($this->debug) {
                 $this->log .= '[ERR] Connection CRYPTO CHECK Failed ...' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Connection CRYPTO CHECK Failed ...');
             }
             //end if
             return 0;
         }
         //end if
     }
     //end if
     //--
     //--
     $this->raw_headers['Host'] = $server . ':' . $port;
     //--
     //-- auth
     if ((string) $user != '' and (string) $pwd != '') {
         //--
         if ($this->debug) {
             $this->log .= '[INF] Authentication will be attempted for USERNAME = \'' . $user . '\' ; PASSWORD(' . strlen($pwd) . ') *****' . "\n";
         }
         //end if
         //--
         $this->raw_headers['Authorization'] = 'Basic ' . base64_encode($user . ':' . $pwd);
         //--
     }
     //end if
     //--
     //-- cookies
     $send_cookies = '';
     //--
     if ($have_cookies) {
         //--
         foreach ($this->cookies as $key => $value) {
             if ((string) $key != '') {
                 if ((string) $value != '') {
                     $send_cookies .= (string) SmartHttpUtils::encode_var_cookie($key, $value);
                 }
                 //end if
             }
             //end if
         }
         //end foreach
         //--
         if ((string) $send_cookies != '') {
             $this->raw_headers['Cookie'] = $send_cookies;
             if ($this->debug) {
                 $this->log .= '[INF] Cookies will be SET: ' . $send_cookies . "\n";
             }
             //end if
         }
         //end if
         //--
     }
     //end if
     //--
     //-- request
     if ((string) $this->jsonrequest != '') {
         // json request
         //--
         if ($this->debug) {
             $this->log .= '[INF] JSON Request will be sent to server via: ' . $this->method . "\n";
         }
         //end if
         //--
         $request = $this->method . ' ' . $path . ' HTTP/' . $this->protocol . "\r\n";
         $this->raw_headers['Content-Type'] = 'application/json';
         $this->raw_headers['Content-Length'] = strlen($this->jsonrequest);
         //--
     } elseif ((string) $this->xmlrequest != '') {
         // xml request
         //--
         if ($this->debug) {
             $this->log .= '[INF] XML Request will be sent to server via: ' . $this->method . "\n";
         }
         //end if
         //--
         $request = $this->method . ' ' . $path . ' HTTP/' . $this->protocol . "\r\n";
         $this->raw_headers['Content-Type'] = 'application/xml';
         // may be also: text/xml
         $this->raw_headers['Content-Length'] = strlen($this->xmlrequest);
         //--
     } elseif ($have_post_vars) {
         // post vars
         //--
         if ((string) $this->method == 'GET') {
             $this->method = 'POST';
             // FIX: if GET Method is using PostVars, then set method to POST ; this should not be fixed for other methods like: HEAD, PUT, DELETE ...
         }
         //end if
         //--
         if ($this->debug) {
             $this->log .= '[INF] Variables will be sent to server using POST method' . "\n";
         }
         //end if
         //--
         $post_string = '';
         if ((string) $this->poststring != '') {
             $post_string = (string) $this->poststring;
         } elseif (is_array($this->postvars)) {
             foreach ($this->postvars as $key => $value) {
                 $post_string .= (string) SmartHttpUtils::encode_var_post($key, $value);
             }
             //end foreach
         }
         //end if else
         //--
         $request = $this->method . ' ' . $path . ' HTTP/' . $this->protocol . "\r\n";
         $this->raw_headers['Content-Type'] = 'application/x-www-form-urlencoded';
         $this->raw_headers['Content-Length'] = strlen($post_string);
         //--
     } else {
         // simple request
         //--
         if ($this->debug) {
             $this->log .= '[INF] Simple Request via: ' . $this->method . "\n";
         }
         //end if
         //--
         $request = $this->method . ' ' . $path . ' HTTP/' . $this->protocol . "\r\n";
         //--
     }
     //end if else
     //--
     //-- check
     if (!$this->socket) {
         //--
         if ($this->debug) {
             $this->log .= '[ERR] Premature connection end (1.1)' . "\n";
             Smart::log_notice('LibHTTP // GetFromURL // Premature connection end (1.1) ... ' . $url);
         }
         //end if
         return 0;
         //--
     }
     //end if
     //--
     //--
     if (@fwrite($this->socket, $request) === false) {
         if ($this->debug) {
             $this->log .= '[ERR] Error writing Request type to socket' . "\n";
             Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Error writing Request type to socket ...');
         }
         //end if
         return 0;
     }
     //end if
     //--
     //-- raw headers
     if (!$this->socket) {
         //--
         if ($this->debug) {
             $this->log .= '[ERR] Premature connection end (1.2)' . "\n";
             Smart::log_notice('LibHTTP // GetFromURL // Premature connection end (1.2) ... ' . $url);
         }
         //end if
         return 0;
         //--
     }
     //end if
     //--
     foreach ($this->raw_headers as $key => $value) {
         if (@fwrite($this->socket, $key . ": " . $value . "\r\n") === false) {
             if ($this->debug) {
                 $this->log .= '[ERR] Error writing Raw-Headers to socket' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Error writing Raw-Headers to socket ...');
             }
             //end if
             return 0;
         }
         //end if
     }
     //end foreach
     //--
     //-- end-line or blank line before post / cookies
     if (!$this->socket) {
         //--
         if ($this->debug) {
             $this->log .= '[ERR] Premature connection end (1.3)' . "\n";
             Smart::log_notice('LibHTTP // GetFromURL // Premature connection end (1.3) ... ' . $url);
         }
         //end if
         return 0;
         //--
     }
     //end if
     //--
     if (@fwrite($this->socket, "\r\n") === false) {
         if ($this->debug) {
             $this->log .= '[ERR] Error writing End-Of-Line to socket' . "\n";
             Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Error writing End-Of-Line to socket ...');
         }
         //end if
         return 0;
     }
     //end if
     //--
     //--
     if ((string) $this->jsonrequest != '') {
         // json request
         //--
         if (!$this->socket) {
             //--
             if ($this->debug) {
                 $this->log .= '[ERR] Premature connection end (1.4)' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL // Premature connection end (1.4) ... ' . $url);
             }
             //end if
             return 0;
             //--
         }
         //end if
         //--
         if (@fwrite($this->socket, $this->jsonrequest . "\r\n") === false) {
             if ($this->debug) {
                 $this->log .= '[ERR] Error writing JSON Request data to socket' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Error writing JSON Request data to socket ...');
             }
             //end if
             return 0;
         }
         //end if
         //--
     } elseif ((string) $this->xmlrequest != '') {
         // xml request
         //--
         if (!$this->socket) {
             //--
             if ($this->debug) {
                 $this->log .= '[ERR] Premature connection end (1.5)' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL // Premature connection end (1.5) ... ' . $url);
             }
             //end if
             return 0;
             //--
         }
         //end if
         //--
         if (@fwrite($this->socket, $this->xmlrequest . "\r\n") === false) {
             if ($this->debug) {
                 $this->log .= '[ERR] Error writing XML Request data to socket' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Error writing XML Request data to socket ...');
             }
             //end if
             return 0;
         }
         //end if
         //--
     } elseif ($have_post_vars) {
         //--
         if (!$this->socket) {
             //--
             if ($this->debug) {
                 $this->log .= '[ERR] Premature connection end (1.6)' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL // Premature connection end (1.6) ... ' . $url);
             }
             //end if
             return 0;
             //--
         }
         //end if
         //--
         if (@fwrite($this->socket, $post_string . "\r\n") === false) {
             if ($this->debug) {
                 $this->log .= '[ERR] Error writing POST data to socket' . "\n";
                 Smart::log_notice('LibHTTP // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // Error writing POST data to socket ...');
             }
             //end if
             return 0;
         }
         //end if
         //--
     }
     //end if else
     //--
     //-- NOTICE: is this necessary ??? appears that not (it was tested a long time without and appear to be faster) ...
     //if(@fwrite($this->socket, "\r\n") === false) {
     //	if($this->debug) {
     //		$this->log .= '[ERR] Error writing EOL to socket'."\n";
     //		Smart::log_notice('LibHTTP // GetFromURL ('.$conex_info.') // Error writing EOL ...'); // FIX: the final \r\n
     //	} //end if
     //} //end if
     //--
     //--
     return 1;
     //--
 }
 public static function High_Load_Monitor()
 {
     //--
     if (is_array(self::$HighLoadMonitorStats)) {
         return (array) self::$HighLoadMonitorStats;
         // avoid re-run and serve from cache
     }
     //end if
     //--
     $tmp_sysload_avg = array();
     //--
     if (defined('SMART_FRAMEWORK_NETSERVER_MAXLOAD')) {
         $tmp_max_load = (int) SMART_FRAMEWORK_NETSERVER_MAXLOAD;
     } else {
         $tmp_max_load = 0;
     }
     //end if
     if ($tmp_max_load > 0) {
         // run only if set to a value > 0
         if (function_exists('sys_getloadavg')) {
             $tmp_sysload_avg = (array) @sys_getloadavg();
             $tmp_sysload_avg[0] = (int) $tmp_sysload_avg[0];
             if ($tmp_sysload_avg[0] > $tmp_max_load) {
                 // protect against system overload over max
                 if (!headers_sent()) {
                     http_response_code(503);
                 } else {
                     Smart::log_notice('#SMART-FRAMEWORK-HIGH-LOAD-PROTECT#' . "\n" . 'SmartFramework // Web :: System Overload Protection: The System is Too Busy ... Try Again Later. The Load Averages reached the maximum allowed value by current settings ... [' . $tmp_sysload_avg[0] . ' of ' . $tmp_max_load . ']');
                 }
                 //end if else
                 die(SmartComponents::http_message_503_serviceunavailable('<h1>503 Service Unavailable - Too busy, try again later</h1><br><b>SmartFramework // Web :: System Overload Protection</b><br>The Load Averages reached the maximum allowed value by current settings ...'));
             }
             //end if
         }
         //end if
     }
     //end if
     //--
     self::$HighLoadMonitorStats = (array) $tmp_sysload_avg;
     //--
     return (array) self::$HighLoadMonitorStats;
     //--
 }
 /**
  * check if DB is opened
  *
  * @access 		private
  * @internal
  *
  */
 private function check_opened()
 {
     if ($this->destroyed !== false) {
         Smart::log_notice('The DataBase: ' . $this->file . ' was not opened or has been already closed !');
     }
     //end if
 }
 /**
  * Function: Get BarCode as PNG
  *
  * @access 		private
  * @internal
  *
  */
 public static function getBarcodePNG($barcode_arr, $z = 3, $color = array(0, 0, 0))
 {
     //--
     if (!is_array($color)) {
         $color = (string) $color;
         $color = trim(str_replace('#', '', $color));
         $color = array(hexdec(substr($color, 0, 2)), hexdec(substr($color, 2, 2)), hexdec(substr($color, 4, 2)));
     }
     //end if
     //--
     if (!is_array($barcode_arr)) {
         //--
         Smart::log_notice('Invalid Barcode2D PNG Data: Not Array !');
         //--
         $width = 125;
         $height = 10;
         //--
         $png = @imagecreate($width, $height);
         $bgcol = @imagecolorallocate($png, 250, 250, 250);
         $fgcol = @imagecolorallocate($png, 255, 0, 0);
         @imagestring($png, 1, 1, 1, "[ INVALID BARCODE (1) ]", $fgcol);
         //--
     } else {
         //--
         $z = self::conformZ($z);
         //-- calculate image size
         $the_width = $barcode_arr['num_cols'] * $z;
         $the_height = $barcode_arr['num_rows'] * $z;
         //--
         $png = null;
         if ($the_width > 0 and $the_height > 0) {
             $png = @imagecreate($the_width, $the_height);
         }
         //end if
         //--
         if (!$png) {
             //--
             Smart::log_notice('Invalid Barcode2D PNG Dimensions: ' . "\n" . 'Code=' . $barcode_arr['code'] . "\n" . 'Cols=' . $barcode_arr['num_cols'] . ' ; Rows=' . $barcode_arr['num_rows']);
             //--
             $width = 125;
             $height = 10;
             //--
             $png = @imagecreate($width, $height);
             $bgcol = @imagecolorallocate($png, 250, 250, 250);
             $fgcol = @imagecolorallocate($png, 255, 0, 0);
             @imagestring($png, 1, 1, 1, "[ INVALID BARCODE (2) ]", $fgcol);
             //--
         } else {
             //--
             $bgcol = @imagecolorallocate($png, 255, 255, 255);
             $fgcol = @imagecolorallocate($png, $color[0], $color[1], $color[2]);
             //-- print barcode elements
             $y = 0;
             //-- for each row
             for ($r = 0; $r < $barcode_arr['num_rows']; ++$r) {
                 //--
                 $x = 0;
                 //-- for each column
                 for ($c = 0; $c < $barcode_arr['num_cols']; ++$c) {
                     //--
                     if ($barcode_arr['bcode'][$r][$c] == 1) {
                         //-- draw a single barcode cell
                         @imagefilledrectangle($png, $x, $y, $x + $z - 1, $y + $z - 1, $fgcol);
                         //--
                     }
                     //end if
                     //--
                     $x += $z;
                     //--
                 }
                 //end for
                 //--
                 $y += $z;
                 //--
             }
             //end for
             //--
         }
         //end if else
         //--
     }
     //end if else
     //--
     ob_start();
     @imagepng($png);
     $imagedata = ob_get_clean();
     @imagedestroy($png);
     //--
     return $imagedata;
     //--
 }
 private function clean_html($y_comments, $y_extra_tags_remove = array(), $y_extra_tags_clean = array(), $y_allowed_tags = array())
 {
     //-- CLEANUP DISSALOWED AND FIX INVALID HTML TAGS
     // * it will use code standardize before to fix active PHP tags and weird characters
     // * will convert all UTF-8 characters to the coresponding HTML-ENTITIES
     // * will remove all tags that are unsafe like <script> or <head> and many other dissalowed unsafe tags
     // * if allowed tags are specified they will take precedence and will be filtered via strip_tags by allowing only these tags, at the end of cleanup to be safer !
     // * if DomDocument is detected and is allowed to be used by current settings will be used finally to do (post-processing) extra cleanup and fixes
     //--
     //--
     if ($this->is_clean != false) {
         return;
         // avoid to re-parse
     }
     //end if
     //--
     $this->is_clean = true;
     //--
     //--
     $this->standardize_html();
     // first, standardize the HTML Code
     //--
     //--
     $arr_tags_0x_list_comments = array('#\\<\\s*?\\!\\-?\\-?(.*?)\\-?\\-?\\>#si');
     //--
     $arr_tags_2x_list_bad = array('head', 'style', 'script', 'noscript', 'frameset', 'frame', 'iframe', 'canvas', 'audio', 'video', 'applet', 'param', 'object', 'form', 'xml', 'xmp', 'o:p');
     if (Smart::array_size($y_extra_tags_remove) > 0) {
         // add extra entries such as: img, p, div, ...
         for ($i = 0; $i < count($y_extra_tags_remove); $i++) {
             if (preg_match((string) $this->regex_tag_name, (string) $y_extra_tags_remove[$i])) {
                 if (!in_array((string) $y_extra_tags_remove[$i], $arr_tags_2x_list_bad)) {
                     $arr_tags_2x_list_bad[] = (string) $y_extra_tags_remove[$i];
                 }
                 //end if
             }
             //end if
         }
         //end for
     }
     //end if
     $arr_tags_2x_repl_bad = (array) $arr_tags_0x_list_comments;
     for ($i = 0; $i < count($arr_tags_0x_list_comments); $i++) {
         $arr_tags_2x_repl_good[] = '<!-- # -->';
         // comment
     }
     //end for
     for ($i = 0; $i < count($arr_tags_2x_list_bad); $i++) {
         $tmp_regex_tag = (array) $this->regex_tag((string) $arr_tags_2x_list_bad[$i]);
         // currently if nested tags some content between those tags may remain not removed ... but that is ok as long as the tag is replaced ; possible fix: match with siU instead of si but will go ungreedy and will match all content until very last end tag ... which may remove too many content
         $arr_tags_2x_repl_bad[] = $tmp_regex_tag['delimiter'] . '(' . $tmp_regex_tag['tag-start'] . ')' . '.*?' . '(' . $tmp_regex_tag['tag-end'] . ')' . $tmp_regex_tag['delimiter'] . 'si';
         // fix: paranthesis are required to correct match in this case (balanced regex)
         $arr_tags_2x_repl_good[] = '<!-- ' . Smart::escape_html((string) $arr_tags_2x_list_bad[$i]) . '/ -->';
     }
     //end if
     //--
     //--
     $arr_tags_1x_list_bad = (array) array_merge((array) $arr_tags_2x_list_bad, array('!doctype', 'html', 'body', 'base', 'meta', 'link', 'track', 'source', 'plaintext', 'marquee'));
     if (Smart::array_size($y_extra_tags_clean) > 0) {
         // add extra entries such as: img, p, div, ...
         for ($i = 0; $i < count($y_extra_tags_clean); $i++) {
             if (preg_match((string) $this->regex_tag_name, (string) $y_extra_tags_clean[$i])) {
                 if (!in_array((string) $y_extra_tags_clean[$i], $arr_tags_1x_list_bad)) {
                     $arr_tags_1x_list_bad[] = (string) $y_extra_tags_clean[$i];
                 }
                 //end if
             }
             //end if
         }
         //end for
     }
     //end if
     $arr_tags_1x_repl_bad = array();
     $arr_tags_1x_repl_good = array();
     for ($i = 0; $i < count($arr_tags_1x_list_bad); $i++) {
         $tmp_regex_tag = (array) $this->regex_tag((string) $arr_tags_1x_list_bad[$i]);
         $arr_tags_1x_repl_bad[] = $tmp_regex_tag['delimiter'] . $tmp_regex_tag['tag-start'] . $tmp_regex_tag['delimiter'] . 'si';
         $arr_tags_1x_repl_bad[] = $tmp_regex_tag['delimiter'] . $tmp_regex_tag['tag-end'] . $tmp_regex_tag['delimiter'] . 'si';
         $arr_tags_1x_repl_good[] = '<!-- ' . Smart::escape_html((string) $arr_tags_1x_list_bad[$i]) . ' -->';
         $arr_tags_1x_repl_good[] = '<!-- /' . Smart::escape_html((string) $arr_tags_1x_list_bad[$i]) . ' -->';
     }
     //end if
     //--
     //--
     $arr_all_repl_bad = (array) array_merge((array) $arr_tags_2x_repl_bad, (array) $arr_tags_1x_repl_bad);
     $arr_all_repl_good = (array) array_merge((array) $arr_tags_2x_repl_good, (array) $arr_tags_1x_repl_good);
     //--
     //print_r($arr_tags_2x_repl_bad);
     //print_r($arr_tags_2x_repl_good);
     //print_r($arr_tags_1x_repl_bad);
     //print_r($arr_tags_1x_repl_good);
     //print_r($arr_all_repl_bad);
     //print_r($arr_all_repl_good);
     //die('');
     //--
     //--
     $this->html = (string) preg_replace((array) $arr_all_repl_bad, (array) $arr_all_repl_good, (string) $this->html);
     //--
     //--
     $this->parse_elements();
     //--
     //--
     for ($i = 0; $i < Smart::array_size($this->elements); $i++) {
         //--
         $code = (string) $this->elements[$i];
         if (substr($code, 0, 4) != '<!--' and (strpos($code, '<') !== false or strpos($code, '>') !== false)) {
             // if valid tag and not a comment
             //--
             $tag_have_endline = false;
             if (substr($code, -1, 1) === "\n") {
                 $tag_have_endline = true;
             }
             //end if
             //--
             $code = trim(str_replace(array("\t", "\n", "\r"), array(' ', ' ', ' '), (string) $code));
             // make tabs and new lines as simple space
             $tmp_parse_attr = (array) $this->get_attributes($code);
             //--
             if (strpos($code, ' ') !== false and Smart::array_size($tmp_parse_attr) > 0) {
                 // tag have attributes
                 //--
                 $tmp_arr = explode(' ', $code);
                 // get tag parts
                 $this->elements[$i] = strtolower((string) $tmp_arr[0]);
                 // recompose the tags
                 foreach ($tmp_parse_attr as $key => $val) {
                     $tmp_is_valid_attr = true;
                     if (!preg_match((string) $this->regex_tag_name, (string) $key)) {
                         $tmp_is_valid_attr = false;
                         // remove invalid attributes
                     } elseif (substr((string) trim((string) $key), 0, 2) == 'on') {
                         $tmp_is_valid_attr = false;
                         // remove attributes starting with 'on' (all JS Events)
                     } elseif (substr((string) trim((string) $key), 0, 10) == 'formaction') {
                         $tmp_is_valid_attr = false;
                         // remove attributes starting with 'formaction'
                     } elseif (substr((string) trim((string) $val), 0, 2) == '&{') {
                         $tmp_is_valid_attr = false;
                         // remove attributes of which value are old Netscape JS ; Ex: border="&{getBorderWidth( )};"
                     } elseif (substr((string) trim((string) $val), 0, 11) == 'javascript:') {
                         $tmp_is_valid_attr = false;
                         // remove attributes that contain javascript:
                     } elseif (stripos((string) trim((string) $val), 'java') !== false and stripos((string) trim((string) $val), 'script') !== false and strpos((string) trim((string) $val), ':') !== false) {
                         $tmp_is_valid_attr = false;
                         // remove attributes that contain java + script + :
                     }
                     //end for
                     if ($tmp_is_valid_attr) {
                         $this->elements[$i] .= ' ' . strtolower($key) . '=' . '"' . str_replace(array('"', '<', '>'), array('&quot;', '&lt;', '&gt;'), (string) $val) . '"';
                     }
                     //end if
                 }
                 //end foreach
                 $this->elements[$i] .= '>';
                 if ($tag_have_endline) {
                     $this->elements[$i] .= "\n";
                 }
                 //end if
                 $tmp_arr = array();
                 //--
             } elseif (preg_match('/^[<' . $this->expr_tag_name . '\\/ >]+$/si', (string) $code)) {
                 // simple tags (includding tags like <br />) ; needs extra / and space
                 //--
                 $this->elements[$i] = strtolower((string) $code);
                 if ($tag_have_endline) {
                     $this->elements[$i] .= "\n";
                 }
                 //end if
                 //--
             } else {
                 //--
                 $this->elements[$i] = '';
                 // invalid tags, clear
                 //--
             }
             //end if
         }
         //end if
         //--
     }
     //end for
     //--
     //--
     $this->html = (string) SmartUnicode::convert_charset((string) implode('', (array) $this->elements), 'UTF-8', 'HTML-ENTITIES');
     //--
     if ($y_comments === false) {
         $this->html = preg_replace((array) $arr_tags_0x_list_comments, '', $this->html);
     }
     //end if
     //--
     //--
     if (Smart::array_size($y_allowed_tags) > 0) {
         $arr_striptags_allow = array();
         for ($i = 0; $i < count($y_allowed_tags); $i++) {
             if (preg_match((string) $this->regex_tag_name, (string) $y_allowed_tags[$i])) {
                 if (!in_array((string) $y_allowed_tags[$i], (array) $arr_striptags_allow)) {
                     // despite if a tag is specified as unallowed, if allowed here will take precedence
                     $arr_striptags_allow[] = '<' . $y_allowed_tags[$i] . '>';
                 }
                 //end if
             }
             //end if
         }
         //end for
         if (Smart::array_size($arr_striptags_allow) > 0) {
             //print_r($arr_striptags_allow);
             $str_striptags_allow = (string) implode(',', (array) $arr_striptags_allow);
             //echo $str_striptags_allow;
             $this->html = (string) strip_tags((string) $this->html, (string) $str_striptags_allow);
         }
         //end if
     }
     //end if
     //--
     //--
     $this->html = (string) trim((string) $this->html);
     //--
     //--
     $use_dom = false;
     //--
     if ($this->dom_processing !== false and class_exists('DOMDocument')) {
         //--
         $use_dom = true;
         //--
         if ((string) $this->html != '') {
             //--
             @libxml_use_internal_errors(true);
             @libxml_clear_errors();
             //--
             $dom = new DOMDocument(5, (string) SMART_FRAMEWORK_CHARSET);
             //--
             $dom->encoding = (string) SMART_FRAMEWORK_CHARSET;
             $dom->strictErrorChecking = false;
             // do not throw errors
             $dom->preserveWhiteSpace = true;
             // do not remove redundant white space
             $dom->formatOutput = true;
             // try to format pretty-print the code
             $dom->resolveExternals = false;
             // disable load external entities from a doctype declaration
             $dom->validateOnParse = false;
             // this must be explicit disabled as if set to true it may try to download the DTD and after to validate (insecure ...)
             //--
             @$dom->loadHTML((string) $this->html, LIBXML_ERR_WARNING | LIBXML_NONET | LIBXML_PARSEHUGE | LIBXML_BIGLINES | LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
             $this->html = (string) @$dom->saveHTML();
             // get back from DOM
             //print_r($this->html);
             unset($dom);
             // clear DOM
             $this->html = (string) trim((string) preg_replace('~<(?:!DOCTYPE|/?(?:html|head|body))[^>]*>\\s*~i', '', (string) $this->html));
             // cleanup ; fixes: normally with the above options will add no doctype or html / body tags, but use it just in case ; alternative to this: explode by body to get content
             //--
             if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes' or $this->dom_log_errors === true) {
                 // log errors if set :: OR ((string)$this->html == '')
                 $errors = (array) @libxml_get_errors();
                 if (Smart::array_size($errors) > 0) {
                     $notice_log = '';
                     foreach ($errors as $z => $error) {
                         if (is_object($error)) {
                             $notice_log .= 'PARSE-ERROR: [' . $the_ercode . '] / Level: ' . $error->level . ' / Line: ' . $error->line . ' / Column: ' . $error->column . ' / Code: ' . $error->code . ' / Message: ' . $error->message . "\n";
                         }
                         //end if
                     }
                     //end foreach
                     if ((string) $notice_log != '') {
                         Smart::log_notice('SmartHtmlParser NOTICE [DOMDocument]:' . "\n" . $notice_log . "\n" . '#END' . "\n");
                     }
                     //end if
                     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                         Smart::log_notice('SmartHtmlParser / Debug HTML-String:' . "\n" . $this->html . "\n" . '#END');
                     }
                     //end if
                 }
                 //end if
             }
             //end if
             //--
             @libxml_clear_errors();
             @libxml_use_internal_errors(false);
             //--
         }
         //end if
         //--
     }
     //end if
     //--
     //--
     if ($this->signature) {
         if ($use_dom) {
             $start_signature = '<!-- Smart/HTML.Cleaner [@] -->';
             $end_signature = '<!-- [/@] Smart/HTML.Cleaner -->';
         } else {
             $start_signature = '<!-- Smart/HTML.Cleaner [#] -->';
             $end_signature = '<!-- [/#] Smart/HTML.Cleaner -->';
         }
         //end if else
     } else {
         $start_signature = '';
         $end_signature = '';
     }
     //end if else
     //--
     //--
     $this->html = (string) $start_signature . $this->html . $end_signature;
     //--
 }
 public static function apply_watermark($imagePath, $watermarkPath, $quality, $gravity)
 {
     //-- check for required extension
     self::check_gd_truecolor();
     //--
     //--
     SmartFileSysUtils::raise_error_if_unsafe_path($imagePath);
     SmartFileSysUtils::raise_error_if_unsafe_path($watermarkPath);
     //--
     //--
     $imagePath = (string) $imagePath;
     $watermarkPath = (string) $watermarkPath;
     //--
     //--
     if (is_file($imagePath) and is_file($watermarkPath)) {
         //--
         $arr_imgsize = (array) @getimagesize($watermarkPath);
         $wtmW = (int) $arr_imgsize[0];
         $wtmH = (int) $arr_imgsize[1];
         $t_wtm = (int) $arr_imgsize[2];
         // OK
         unset($arr_imgsize);
         //--
         if ($t_wtm <= 0) {
             Smart::log_notice('Media Gallery // SmartGdImageProcess // Watermark :: Unknown Type [W]: ' . $watermarkPath);
             return 1;
             // not ok (unknown type)
         }
         //end if
         $t_wtm = (string) @image_type_to_mime_type((int) $t_wtm);
         // OK
         //--
         switch ((string) $t_wtm) {
             case 'image/png':
             case 'image/x-png':
                 $watermark = @imagecreatefrompng($watermarkPath);
                 break;
             case 'image/gif':
                 $watermark = @imagecreatefromgif($watermarkPath);
                 break;
             case 'image/pjpeg':
             case 'image/jpeg':
             case 'image/jpg':
                 $watermark = @imagecreatefromjpeg($watermarkPath);
                 break;
             default:
                 Smart::log_notice('Media Gallery // SmartGdImageProcess // Watermark :: Unsupported Type [W] (not PNG/GIF/JPEG ; Type=' . $t_wtm . '): ' . $watermarkPath);
                 return 1;
                 // not ok (invalid type)
         }
         //end switch
         //--
         if (!is_resource($watermark)) {
             // if the immage is corrupt or invalid ...
             Smart::log_warning('Media Gallery // SmartGdImageProcess // Watermark :: Source Watermark Image Failure: ' . $watermarkPath);
             return 2;
             // not ok (there was an error reading the image / have no privileges / or may be an invalid image type)
         }
         //end if
         //--
         //--
         $arr_imgsize = (array) @getimagesize($imagePath);
         $imgW = (int) $arr_imgsize[0];
         $imgH = (int) $arr_imgsize[1];
         $t_img = (int) $arr_imgsize[2];
         // OK
         unset($arr_imgsize);
         //--
         if ($t_img <= 0) {
             Smart::log_notice('Media Gallery // SmartGdImageProcess // Watermark :: Unknown Type [I]: ' . $imagePath);
             return 3;
             // not ok (unknown type)
         }
         //end if
         $t_img = (string) @image_type_to_mime_type((int) $t_img);
         // OK
         //--
         switch ((string) $t_img) {
             case 'image/png':
             case 'image/x-png':
                 $the_type = 'png';
                 $source = @imagecreatefrompng($imagePath);
                 break;
             case 'image/gif':
                 $the_type = 'gif';
                 $source = @imagecreatefromgif($imagePath);
                 break;
             case 'image/pjpeg':
             case 'image/jpeg':
             case 'image/jpg':
                 $the_type = 'jpg';
                 $source = @imagecreatefromjpeg($imagePath);
                 break;
             default:
                 Smart::log_notice('Media Gallery // SmartGdImageProcess // Watermark :: Unsupported Type [I] (not PNG/GIF/JPEG ; Type=' . $t_img . '): ' . $imagePath);
                 return 3;
                 // not ok (invalid type)
         }
         //end switch
         //--
         if (!is_resource($source)) {
             // if the immage is corrupt or invalid ...
             Smart::log_warning('Media Gallery // SmartGdImageProcess // Watermark :: Source Image Failure: ' . $watermarkPath);
             return 4;
             // not ok (there was an error reading the image / have no privileges / or may be an invalid image type)
         }
         //end if
         //--
         //-- apply watermark
         switch ((string) $gravity) {
             // {{{SYNC-GRAVITY}}}
             case 'northwest':
                 $gravityX = 0;
                 $gravityY = 0;
                 break;
             case 'northeast':
                 $gravityX = ceil($imgW - $wtmW);
                 $gravityY = 0;
                 break;
             case 'southwest':
                 $gravityX = 0;
                 $gravityY = ceil($imgH - $wtmH);
                 break;
             case 'southeast':
                 $gravityX = ceil($imgW - $wtmW);
                 $gravityY = ceil($imgH - $wtmH);
                 break;
             case 'center':
             default:
                 $gravityX = ceil($imgW / 2 - $wtmW / 2);
                 $gravityY = ceil($imgH / 2 - $wtmH / 2);
         }
         //end switch
         //--
         @imagecopy($source, $watermark, $gravityX, $gravityY, 0, 0, $wtmW, $wtmH);
         //--
         //-- saving new image
         switch ((string) $the_type) {
             case 'png':
                 @imagepng($source, $imagePath);
                 break;
             case 'gif':
                 @imagegif($source, $imagePath);
                 break;
             case 'jpg':
                 @imagejpeg($source, $imagePath, $quality);
                 // preserve 100% quality for jpeg
                 break;
             default:
                 // this should not happen, it is catched above
         }
         //end switch
         //--
         //--
         @imagedestroy($source);
         @imagedestroy($watermark);
         //--
         //--
         return 0;
         // OK
         //--
     }
     //end if else
     //--
     //--
     return -1;
     // not ok, files do not exists / not files / invalid paths provided
     //--
 }
 /**
  * Start the Session on request
  *
  */
 public static function start()
 {
     //=====
     //--
     if (self::$started !== false) {
         return;
         // avoid start session if already started ...
     }
     //end if
     self::$started = true;
     // avoid run start again
     //--
     //=====
     //--
     $browser_os_ip_identification = SmartUtils::get_os_browser_ip();
     // get browser and os identification
     //--
     if ((string) $browser_os_ip_identification['bw'] == '@s#' or (string) $browser_os_ip_identification['bw'] == 'bot') {
         return;
         // in this case start no session for robots or the self browser (as they do not need to share info between many visits) ; if the self browser fail to identify will be at least identified as robot in the worst case
     }
     //end if
     //--
     //=====
     //-- no log as the cookies can be dissalowed by the browser
     if ((string) SMART_APP_VISITOR_COOKIE == '') {
         return;
         // session need cookies
     }
     //end if
     //--
     //=====
     //--
     $sf_sess_mode = 'files';
     $sf_sess_area = 'default-sess';
     $sf_sess_ns = 'unknown';
     $sf_sess_dir = 'tmp/sess';
     //--
     //=====
     if (!defined('SMART_FRAMEWORK_SESSION_PREFIX')) {
         Smart::log_warning('FATAL ERROR: Invalid Session Prefix :: SMART_FRAMEWORK_SESSION_PREFIX');
         return;
     }
     //end if
     if (strlen(SMART_FRAMEWORK_SESSION_PREFIX) < 3 or strlen(SMART_FRAMEWORK_SESSION_PREFIX) > 9) {
         Smart::log_warning('WARNING: Session Prefix must have a length between 3 and 9 characters :: SMART_FRAMEWORK_SESSION_PREFIX');
         return;
     }
     //end if
     if (!preg_match('/^[a-z\\-]+$/', (string) SMART_FRAMEWORK_SESSION_PREFIX)) {
         Smart::log_warning('WARNING: Session Prefix contains invalid characters :: SMART_FRAMEWORK_SESSION_PREFIX');
         return;
     }
     //end if
     //--
     if (!defined('SMART_FRAMEWORK_SESSION_NAME')) {
         Smart::log_warning('FATAL ERROR: Invalid Session Name :: SMART_FRAMEWORK_SESSION_NAME');
         return;
     }
     //end if
     if (strlen(SMART_FRAMEWORK_SESSION_NAME) < 10 or strlen(SMART_FRAMEWORK_SESSION_NAME) > 25) {
         Smart::log_warning('WARNING: Session Name must have a length between 10 and 25 characters :: SMART_FRAMEWORK_SESSION_NAME');
         return;
     }
     //end if
     if (!preg_match('/^[_A-Za-z0-9]+$/', (string) SMART_FRAMEWORK_SESSION_NAME)) {
         Smart::log_warning('WARNING: Session Name contains invalid characters :: SMART_FRAMEWORK_SESSION_NAME');
         return;
     }
     //end if
     if (!SmartFrameworkSecurity::ValidateVariableName(strtolower(SMART_FRAMEWORK_SESSION_NAME))) {
         Smart::log_warning('WARNING: Session Name have an invalid value :: SMART_FRAMEWORK_SESSION_NAME');
         return;
     }
     //end if
     //--
     if (!defined('SMART_FRAMEWORK_SESSION_LIFETIME')) {
         Smart::log_warning('FATAL ERROR: Invalid Session GC Lifetime :: SMART_FRAMEWORK_SESSION_LIFETIME');
         return;
     }
     //end if
     if (!is_int(SMART_FRAMEWORK_SESSION_LIFETIME)) {
         Smart::log_warning('Invalid INIT constant value for SMART_FRAMEWORK_SESSION_LIFETIME');
         return;
     }
     //end if
     //--
     if (!is_dir('tmp/sessions/')) {
         Smart::log_warning('FATAL ERROR: The Folder \'tmp/sessions/\' does not exists for use with Session !');
         return;
     }
     //end if
     //--
     $detected_session_mode = (string) ini_get('session.save_handler');
     if ((string) $detected_session_mode === 'files') {
         if ((string) SMART_FRAMEWORK_SESSION_HANDLER !== 'files') {
             Smart::log_warning('FATAL ERROR: The value set for SMART_FRAMEWORK_SESSION_HANDLER is not set to: files / but the value found in session.save_handler is: ' . $detected_session_mode);
             return;
         }
         //end if
     } elseif ((string) $detected_session_mode === 'user') {
         if ((string) SMART_FRAMEWORK_SESSION_HANDLER === 'files') {
             Smart::log_warning('FATAL ERROR: The value set for SMART_FRAMEWORK_SESSION_HANDLER is set to: files / but the value found in session.save_handler is: ' . $detected_session_mode);
             return;
         }
         //end if
     } else {
         Smart::log_warning('FATAL ERROR: The value set for session.save_handler must be set to one of these modes: files or user');
         return;
     }
     //end if
     //--
     //=====
     //--  generate a the client private key based on it's IP and Browser
     $the_sess_client_uuid = SmartUtils::unique_client_private_key();
     // SHA512 key to protect session data agains forgers
     //-- a very secure approach based on a chain, derived with a secret salt from the framework security key:
     // (1) an almost unique client private key lock based on it's IP and Browser
     // (2) an entropy derived from the client random cookie combined with the (1)
     // (3) a unique session name suffix derived from (1) and (2)
     // (4) a unique session id composed from (1) and (2)
     //-- thus the correlation between the random public client cookie, the session name suffix and the session id makes impossible to forge it as it locks to IP+Browser, using a public entropy cookie all encrypted with a secret key and derived and related, finally composed.
     $the_sess_client_lock = SmartHashCrypto::sha1(SMART_FRAMEWORK_SECURITY_KEY . '#' . $the_sess_client_uuid);
     $the_sess_client_entropy = SmartHashCrypto::sha1(SMART_APP_VISITOR_COOKIE . '*' . $the_sess_client_uuid . '%' . SMART_FRAMEWORK_SECURITY_KEY);
     $the_sess_nsuffix = SmartHashCrypto::sha1($the_sess_client_uuid . ':' . SMART_FRAMEWORK_SECURITY_KEY . '^' . $the_sess_client_entropy . '+' . $the_sess_client_lock . '$' . SMART_APP_VISITOR_COOKIE);
     $the_sess_id = $the_sess_client_entropy . '-' . $the_sess_client_lock;
     // session ID combines the secret client key based on it's IP / Browser and the Client Entropy Cookie
     //--
     $sf_sess_area = Smart::safe_filename((string) SMART_FRAMEWORK_SESSION_PREFIX);
     $sf_sess_dpfx = substr($the_sess_client_entropy, 0, 1) . '-' . substr($the_sess_client_lock, 0, 1);
     // this come from hexa so 3 chars are 16x16x16=4096 dirs
     //--
     if ((string) $browser_os_ip_identification['bw'] == '@s#') {
         $sf_sess_ns = '@sr-' . $sf_sess_dpfx;
     } elseif ((string) $browser_os_ip_identification['bw'] == 'bot') {
         $sf_sess_ns = 'r0-' . $sf_sess_dpfx;
         // we just need a short prefix for robots (on disk is costly for GC to keep separate folders, but of course, not so safe)
     } else {
         $sf_sess_ns = 'c-' . substr($browser_os_ip_identification['bw'], 0, 3) . '-' . $sf_sess_dpfx;
         // we just need a short prefix for clients (on disk is costly for GC to keep separate folders, but of course, not so safe)
     }
     //end if else
     $sf_sess_ns = Smart::safe_filename($sf_sess_ns);
     //-- by default set for files
     $sf_sess_mode = 'files';
     $sf_sess_dir = 'tmp/sessions/' . $sf_sess_area . '/' . $sf_sess_ns . '/';
     if ((string) $detected_session_mode === 'user') {
         if (class_exists('SmartCustomSession')) {
             if ((string) get_parent_class('SmartCustomSession') == 'SmartAbstractCustomSession') {
                 $sf_sess_mode = 'user-custom';
                 $sf_sess_dir = 'tmp/sessions/' . $sf_sess_area . '/';
                 // here the NS is saved in DB so we do not need to complicate paths
             } else {
                 Smart::log_warning('SESSION INIT ERROR: Invalid Custom Session Handler. The class SmartCustomSession must be extended from class SmartAbstractCustomSession ...');
                 return;
             }
             //end if else
         } else {
             Smart::log_warning('SESSION INIT ERROR: Custom Session Handler requires the class SmartCustomSession ...');
             return;
         }
         //end if
     }
     //end if
     $sf_sess_dir = Smart::safe_pathname($sf_sess_dir);
     //--
     if (!is_dir($sf_sess_dir)) {
         SmartFileSystem::dir_recursive_create($sf_sess_dir);
     }
     //end if
     SmartFileSystem::write_if_not_exists('tmp/sessions/' . $sf_sess_area . '/' . 'index.html', '');
     //=====
     //--
     @session_save_path($sf_sess_dir);
     @session_cache_limiter('nocache');
     //--
     $the_name_of_session = (string) SMART_FRAMEWORK_SESSION_NAME . '__Key_' . $the_sess_nsuffix;
     // protect session name data agains forgers
     //--
     @session_id((string) $the_sess_id);
     @session_name((string) $the_name_of_session);
     //--
     $tmp_exp_seconds = Smart::format_number_int(SMART_FRAMEWORK_SESSION_LIFETIME, '+');
     if ($tmp_exp_seconds > 0) {
         @session_set_cookie_params((int) $tmp_exp_seconds, '/');
         // session cookie expire and the path
     }
     // end if
     //-- be sure that session_write_close() is executed at the end of script if script if die('') premature and before pgsql shutdown register in the case of DB sessions
     register_shutdown_function('session_write_close');
     //-- handle custom session handler
     if ((string) $sf_sess_mode === 'user-custom') {
         //--
         $sess_obj = new SmartCustomSession();
         $sess_obj->sess_area = (string) $sf_sess_area;
         $sess_obj->sess_ns = (string) $sf_sess_ns;
         $sess_obj->sess_expire = (int) $tmp_exp_seconds;
         //--
         session_set_save_handler(array($sess_obj, 'open'), array($sess_obj, 'close'), array($sess_obj, 'read'), array($sess_obj, 'write'), array($sess_obj, 'destroy'), array($sess_obj, 'gc'));
         //--
     }
     //end if else
     //-- start session
     @session_start();
     //--
     if ((string) $_SESSION['SoftwareFramework_VERSION'] != (string) SMART_FRAMEWORK_VERSION or (string) $_SESSION['website_ID'] != (string) SMART_SOFTWARE_NAMESPACE or strlen($_SESSION['session_ID']) < 32) {
         //--
         $_SESSION['SoftwareFramework_VERSION'] = (string) SMART_FRAMEWORK_VERSION;
         // software version
         $_SESSION['SoftwareFramework_SessionMode'] = (string) $sf_sess_mode;
         // session mode
         $_SESSION['website_ID'] = (string) SMART_SOFTWARE_NAMESPACE;
         // the website ID
         $_SESSION['uniqbrowser_ID'] = (string) $the_sess_client_uuid;
         // a true unique browser ID (this is a protection against sessionID forgers)
         $_SESSION['session_ID'] = (string) @session_id();
         // read current session ID
         $_SESSION['session_STARTED'] = (string) date('Y-m-d H:i:s O');
         // read current session ID
         //--
     }
     //end if
     //--
     if (!isset($_SESSION['visit_COUNTER'])) {
         $_SESSION['visit_COUNTER'] = 1;
     } else {
         $_SESSION['visit_COUNTER'] += 1;
     }
     //end if else
     //--
     $_SESSION['SmartFramework__Browser__Identification__Data'] = (array) $browser_os_ip_identification;
     //--
     if ((string) $_SESSION['uniqbrowser_ID'] != (string) $the_sess_client_uuid) {
         // we need at least a md5 session
         //-- log, then unset old session (these are not well tested ...)
         Smart::log_notice('Session Security Breakpoint :: Session-BrowserUniqueID = ' . $_SESSION['uniqbrowser_ID'] . "\n" . 'SessionSecurityUniqueID = ' . $the_sess_client_uuid . "\n" . 'Browser Ident = ' . $browser_os_ip_identification['bw'] . "\n" . 'Cookies = ' . print_r($_COOKIE, 1) . "\n" . 'SessID = ' . $_SESSION['session_ID'] . "\n" . 'ClientIP = ' . SmartUtils::get_ip_client() . ' @ ' . $_SERVER['REMOTE_ADDR'] . "\n" . 'UserAgent = ' . $_SERVER['HTTP_USER_AGENT']);
         $_SESSION = array();
         // reset it
         //-- unset the cookie (from this below is tested)
         @setcookie($the_name_of_session, 'EXPIRED', 1, '/');
         //-- stop execution with message
         Smart::raise_error('SESSION // SECURITY BREAK POINT: Possible Session Forgery Detected ...', 'SESSION // SECURITY BREAK POINT: Possible Session Forgery Detected ! Please refresh the page ... A new session will be assigned ! If you are not trying to forge another user\' session this situation can occur also if you are behind a proxy and some of your navigation parameters has been changed ! If this problem persist try to restart your browser or use other browser. If still persist, contact the website administrator');
         die('');
         // just in case
         return;
         // or is better to silent discard it ?
         //--
     }
     //end if
     //--
     self::$active = time();
     // successfuly started
     //--
 }
 /**
  * Generate a PDF Document on the fly from a piece of HTML code.
  *
  * Notice: this is using a secured cache folder, unique per visitor ID
  *
  * @param STRING $y_html_content				:: The HTML Code
  * @param ENUM $y_orientation					:: Page Orientation: 'normal' | 'wide'
  * @param STRING $y_runtime_script 				:: The allowed Runtime Script to allow send credentials for sub-downloads. Ex: admin.php
  * @param STRING $y_runtime_url					:: The allowed Runtime URL ended by '/' to allow send credentials for sub-downloads. Ex: http(s)://some-server/some_path/ ; normally this should be set in config to enforce https:// and a single URL only
  * @param BOOLEAN $y_allow_send_credentials 	:: Set to TRUE to allow or set to FALSE to dissalow sending the auth credentials for sub-downloads: in the case there are embedded pictures generated by admin.php which may need authentication before to work, the credentials need to be set automatically in this case
  *
  * @returns STRING 							:: The PDF Document Contents
  *
  */
 public static function generate($y_html_content, $y_orientation = 'normal', $y_runtime_script = '', $y_runtime_url = '', $y_allow_send_credentials = false)
 {
     //--
     $pdfdata = '';
     //--
     $htmldoc = self::is_active();
     //--
     if ((string) $htmldoc != '') {
         //--
         if ((string) $y_orientation == 'wide') {
             $orientation = self::tag_page_wide();
         } else {
             $orientation = self::tag_page_normal();
         }
         //end if else
         //--
         $tmp_prefix_dir = 'tmp/cache/pdf/';
         $protect_file = $tmp_prefix_dir . '.htaccess';
         $dir = $tmp_prefix_dir . SMART_FRAMEWORK_SESSION_PREFIX . '/';
         // we use different for index / admin / @
         //--
         $uniquifier = SmartUtils::unique_auth_client_private_key() . SMART_APP_VISITOR_COOKIE;
         $the_dir = $dir . Smart::safe_varname(Smart::uuid_10_seq() . '_' . Smart::uuid_10_num() . '_' . SmartHashCrypto::sha1($uniquifier)) . '/';
         //--
         $tmp_uuid = Smart::uuid_45($uniquifier) . Smart::uuid_36($uniquifier);
         $file = $the_dir . '__document_' . SmartHashCrypto::sha256('@@PDF#File::Cache@@' . $tmp_uuid) . '.html';
         $logfile = $the_dir . '__headers_' . SmartHashCrypto::sha256('@@PDF#File::Cache@@' . $tmp_uuid) . '.log';
         //--
         if (is_dir($the_dir)) {
             SmartFileSystem::dir_delete($the_dir);
         }
         //end if
         //--
         if (!is_dir($the_dir)) {
             SmartFileSystem::dir_recursive_create($the_dir);
         }
         // end if
         //--
         SmartFileSystem::write_if_not_exists($protect_file, trim(SMART_FRAMEWORK_HTACCESS_FORBIDDEN) . "\n", 'yes');
         //-- process the code
         $y_html_content = (string) self::remove_between_tags((string) $y_html_content);
         $y_html_content = (string) self::safe_charset((string) $y_html_content);
         //-- extract images
         $htmlparser = new SmartHtmlParser((string) $y_html_content);
         $arr_imgs = $htmlparser->get_tags('img');
         $htmlparser = '';
         unset($htmlparser);
         //--
         $chk_duplicates_arr = array();
         //--
         for ($i = 0; $i < Smart::array_size($arr_imgs); $i++) {
             //--
             $tmp_img_src = trim((string) $arr_imgs[$i]['src']);
             //--
             if (strlen($chk_duplicates_arr[$tmp_img_src]) <= 0) {
                 //--
                 $tmp_url_img_src = '';
                 //--
                 if ((string) $y_runtime_script != '' and (string) $y_runtime_url != '') {
                     // replace relative paths
                     if (substr($tmp_img_src, 0, @strlen($y_runtime_script)) == (string) $y_runtime_script) {
                         $tmp_url_img_src = (string) $y_runtime_url . $tmp_img_src;
                         $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $tmp_url_img_src . '"', (string) $y_html_content);
                         $tmp_img_src = (string) $tmp_url_img_src;
                     }
                     //end if
                 }
                 //end if
                 //--
                 $tmp_img_ext = '.' . strtolower(SmartFileSysUtils::get_file_extension_from_path($tmp_img_src));
                 // [OK]
                 $tmp_img_cache = 'pdf_img_' . SmartHashCrypto::sha256('@@PDF#File::Cache::IMG@@' . '#' . $i . '@' . $tmp_img_src . '//' . $tmp_uuid);
                 //--
                 $tmp_arr = array();
                 //--
                 if (substr($tmp_img_src, 0, 7) == 'http://' or substr($tmp_img_src, 0, 8) == 'https://') {
                     //--
                     $tmp_img_ext = '';
                     // we clear the extension as we don't know yet (we will get it from headers)
                     $tmp_img_cache = 'pdf_url_img_' . SmartHashCrypto::sha256('@@PDF#File::Cache::URL::IMG@@' . '#' . $i . '@' . $tmp_img_src . '//' . $tmp_uuid);
                     //--
                 }
                 //end if
                 //--
                 if ($y_allow_send_credentials === true) {
                     $allow_set_credentials = 'yes';
                 } else {
                     $allow_set_credentials = 'no';
                 }
                 //end if else
                 //--
                 $tmp_arr = SmartUtils::load_url_or_file($tmp_img_src, SMART_FRAMEWORK_NETSOCKET_TIMEOUT, 'GET', '', '', '', $allow_set_credentials);
                 // [OK] :: allow set credentials
                 //--
                 $tmp_img_ext = '.noextension';
                 $tmp_where_we_guess = '';
                 //--
                 $guess_arr = array();
                 //--
                 $guess_arr = SmartUtils::guess_image_extension_by_url_head($tmp_arr['headers']);
                 $tmp_img_ext = (string) $guess_arr['extension'];
                 $tmp_where_we_guess = (string) $guess_arr['where-was-detected'];
                 $guess_arr = array();
                 if ((string) $tmp_img_ext == '') {
                     $tmp_img_ext = SmartUtils::guess_image_extension_by_first_bytes(substr($tmp_arr['content'], 0, 256));
                     if ((string) $tmp_img_ext != '') {
                         $tmp_where_we_guess = ' First Bytes ...';
                     }
                     //end if
                 }
                 //end if
                 //--
                 if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                     // if debug, append information to log
                     SmartFileSystem::write($logfile, '####################' . "\n" . '#################### [FILE # ' . $i . ' = \'' . $tmp_img_src . '\']' . "\n\n" . '==== [MODE] :: ' . $tmp_arr['mode'] . "\n" . '==== [LOG] :: ' . "\n" . $tmp_arr['log'] . "\n" . '==== [HEADERS] ::' . "\n" . $tmp_arr['headers'] . "\n" . '########' . "\n" . '==== [GUESS EXTENSION] :: ' . $tmp_where_we_guess . "\n\n" . '###################' . "\n\n\n\n", 'a');
                 }
                 //end if
                 //--
                 if ((string) $tmp_arr['result'] == '1' and (string) $tmp_arr['code'] == '200') {
                     //--
                     SmartFileSystem::write($the_dir . $tmp_img_cache . $tmp_img_ext, $tmp_arr['content']);
                     //-- if empty, it may be a file
                     if ((string) $tmp_img_ext == '' or (string) $tmp_img_ext == '.png' or (string) $tmp_img_ext == '.gif' or (string) $tmp_img_ext == '.jpg') {
                         $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $tmp_img_cache . $tmp_img_ext . '"', (string) $y_html_content);
                     } else {
                         // we want to avoid html code to be loaded as image by mistakes of http browser class or servers
                         $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $y_runtime_url . 'lib/framework/img/sign_warn.png"', (string) $y_html_content);
                     }
                     //end if else
                     //--
                 } else {
                     //--
                     $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $y_runtime_url . 'lib/framework/img/sign_error.png"', (string) $y_html_content);
                     //--
                 }
                 //end if
                 //--
             }
             //end if
             //--
             $chk_duplicates_arr[$tmp_img_src] = 'processed';
             //--
         }
         //end for
         //--
         $chk_duplicates_arr = array();
         unset($chk_duplicates_arr);
         $arr_imgs = array();
         unset($arr_imgs);
         //--
         SmartFileSystem::write($file, $orientation . "\n" . $y_html_content);
         //--
         if (is_file($file)) {
             //--
             ob_start();
             //--
             @passthru($htmldoc . ' ' . self::pdf_options($file));
             //--
             $pdfdata = ob_get_clean();
             //--
         } else {
             //--
             Smart::log_warning('ERROR: PDF Generator Failed to find the PDF Document: ' . $file . "\n" . $y_html_content);
             //--
         }
         //end if else
         //-- cleanup
         if ((string) SMART_FRAMEWORK_DEBUG_MODE != 'yes') {
             // if not debug, cleanup the dir
             if (is_dir($the_dir)) {
                 SmartFileSystem::dir_delete($the_dir);
             }
             //end if
         }
         //end if
         //--
     } else {
         //--
         Smart::log_notice('NOTICE: PDF Generator is INACTIVE ...');
         //--
     }
     //end if
     //--
     return (string) $pdfdata;
     //--
 }
 /**
  * Load a File or an URL
  * it may use 3 methods: FileRead, CURL or HTTP-Browser class
  *
  * @param STRING 	$y_url_or_path			:: /path/to/file | http(s)://some.url:port/path (port is optional)
  * @param NUMBER 	$y_timeout				:: timeout in seconds
  * @param ENUM 		$y_method 				:: used only for URLs, the browsing method: GET | POST
  * @param ENUM		$y_ssl_method			:: SSL Mode: tls | sslv3 | sslv2 | ssl
  * @param STRING 	$y_auth_name			:: used only for URLs, the auth user name
  * @param STRING 	$y_auth_pass			:: used only for URLs, the auth password
  * @param YES/NO	y_allow_set_credentials	:: DEFAULT MUST BE set to NO ; if YES must be set just for internal URLs ; if the $y_url_or_path to get is detected to be under current URL will send also the Unique / session IDs ; more if detected that is from admin.php and if this is set to YES will send the HTTP-BASIC Auth credentials if detected (using YES with other URLs than SmartFramework's current URL can be a serious SECURITY ISSUE, so don't !)
  */
 public static function load_url_or_file($y_url_or_path, $y_timeout = 30, $y_method = 'GET', $y_ssl_method = '', $y_auth_name = '', $y_auth_pass = '', $y_allow_set_credentials = 'no')
 {
     //-- v.2016-01-15
     // fixed sessionID with new Dynamic generated
     // TODO: use the CURL to browse also FTP and SSH ...
     //--
     $y_url_or_path = (string) $y_url_or_path;
     //--
     if ((string) $y_url_or_path == '') {
         //--
         return array('log' => 'ERROR: FILE Name is Empty ...', 'mode' => 'file', 'result' => '0', 'code' => '400', 'headers' => '', 'content' => '', 'debuglog' => '');
         //--
     }
     //end if
     //-- detect if file or url
     if (substr($y_url_or_path, 0, 7) == 'http://' or substr($y_url_or_path, 0, 8) == 'https://') {
         $is_file = 0;
         // it is a url
     } else {
         $is_file = 1;
         // it is a file
     }
     //end if
     //--
     if ($is_file == 1) {
         //--
         $y_url_or_path = trim($y_url_or_path);
         //-- try to detect if data:image/ :: {{{SYNC-DATA-IMAGE}}}
         if (strtolower(substr($y_url_or_path, 0, 11)) == 'data:image/' and stripos($y_url_or_path, ';base64,') !== false) {
             //--
             $eimg = explode(';base64,', $y_url_or_path);
             //--
             return array('log' => 'OK ? Not sure, decoded from embedded b64 image: ', 'mode' => 'embedded', 'result' => '1', 'code' => '200', 'headers' => SmartUnicode::sub_str($y_url_or_path, 0, 50) . '...', 'content' => @base64_decode(trim($eimg[1])), 'debuglog' => '');
             //--
         } elseif (is_file($y_url_or_path)) {
             //--
             return array('log' => 'OK: FILE Exists', 'mode' => 'file', 'result' => '1', 'code' => '200', 'headers' => 'Content-Disposition: inline; filename="' . basename($y_url_or_path) . '"' . "\n", 'content' => SmartFileSystem::read($y_url_or_path), 'debuglog' => '');
             //--
         } else {
             //--
             return array('log' => 'ERROR: FILE Not Found or Invalid Data ...', 'mode' => 'file', 'result' => '0', 'code' => '404', 'headers' => '', 'content' => '', 'debuglog' => '');
             //--
         }
         //end if else
         //--
     } else {
         //--
         if ((string) $y_ssl_method == '') {
             if (defined('SMART_FRAMEWORK_SSL_MODE')) {
                 $y_ssl_method = (string) SMART_FRAMEWORK_SSL_MODE;
             } else {
                 Smart::log_notice('NOTICE: LibUtils/Load-URL-or-File // The SSL Method not defined and SMART_FRAMEWORK_SSL_MODE was not defined. Using the `tls` as default ...');
                 $y_ssl_method = 'tls';
             }
             //end if else
         }
         //end if
         //--
         $browser = new SmartHttpClient();
         //--
         $y_timeout = Smart::format_number_int($y_timeout, '+');
         if ($y_timeout <= 0) {
             $y_timeout = 30;
             // default value
         }
         //end if
         $browser->connect_timeout = (int) $y_timeout;
         //--
         if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
             $browser->debug = 1;
         }
         //end if
         //--
         if ((string) self::get_server_current_protocol() == 'https://') {
             $tmp_current_protocol = 'https://';
         } else {
             $tmp_current_protocol = 'http://';
         }
         //end if else
         //--
         $tmp_current_server = self::get_server_current_domain_name();
         $tmp_current_port = self::get_server_current_port();
         //--
         $tmp_current_path = self::get_server_current_request_uri();
         $tmp_current_script = self::get_server_current_full_script();
         //--
         $tmp_test_url_arr = Smart::separe_url_parts($y_url_or_path);
         $tmp_test_browser_id = self::get_os_browser_ip();
         //--
         $tmp_extra_log = '';
         if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
             $tmp_extra_log .= "\n" . '===== # =====' . "\n";
         }
         //end if
         //--
         $cookies = array();
         $auth_name = (string) $y_auth_name;
         $auth_pass = (string) $y_auth_pass;
         //--
         if ((string) $y_allow_set_credentials == 'yes') {
             //--
             if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                 $tmp_extra_log .= '[EXTRA]: I will try to detect if this is my current Domain and I will check if it is safe to send my sessionID COOKIE and my Auth CREDENTIALS ...' . "\n";
             }
             //end if
             //--
             if ((string) $tmp_current_protocol == (string) $tmp_test_url_arr['protocol'] and (string) $tmp_current_server == (string) $tmp_test_url_arr['server'] and (string) $tmp_current_port == (string) $tmp_test_url_arr['port']) {
                 //--
                 if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                     $tmp_extra_log .= '[EXTRA]: OK, Seems that the browsed Domain is identical with my current Domain which is: ' . $tmp_current_protocol . $tmp_current_server . ':' . $tmp_current_port . ' and the browsed one is: ' . $tmp_test_url_arr['protocol'] . $tmp_test_url_arr['server'] . ':' . $tmp_test_url_arr['port'] . "\n";
                     $tmp_extra_log .= '[EXTRA]: I will also check if my current script and path are identical with the browsed ones ...' . "\n";
                 }
                 //end if
                 //--
                 if ((string) $tmp_current_script == (string) $tmp_test_url_arr['scriptname'] and substr($tmp_current_path, 0, strlen($tmp_current_script)) == (string) $tmp_test_url_arr['scriptname']) {
                     //--
                     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                         $tmp_extra_log .= '[EXTRA]: OK, Seems that the current script is identical with the browsed one :: ' . 'Current Path is: \'' . $tmp_current_script . '\' / Browsed Path is: \'' . $tmp_test_url_arr['scriptname'] . '\' !' . "\n";
                         $tmp_extra_log .= '[EXTRA]: I will check if I have to send my SessionID so I will check the browserID ...' . "\n";
                     }
                     //end if
                     //--
                     $browser->useragent = (string) self::get_selfrobot_useragent_name();
                     // this must be set just when detected the same path and script ; it is a requirement to detect it as the self-robot [ @s# ] in order to send the credentials or the current
                     //-- {{{SYNC-SMART-UNIQUE-COOKIE}}}
                     if (defined('SMART_FRAMEWORK_UNIQUE_ID_COOKIE_NAME') and !defined('SMART_FRAMEWORK_UNIQUE_ID_COOKIE_SKIP')) {
                         if ((string) SMART_FRAMEWORK_UNIQUE_ID_COOKIE_NAME != '') {
                             if (SmartFrameworkSecurity::ValidateVariableName(strtolower((string) SMART_FRAMEWORK_UNIQUE_ID_COOKIE_NAME))) {
                                 //--
                                 if ((string) SMART_APP_VISITOR_COOKIE != '') {
                                     // if set, then forward
                                     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                                         $tmp_extra_log .= '[EXTRA]: OK, I will send my current Visitor Unique Cookie ID as it is set and not empty ...' . "\n";
                                     }
                                     //end if
                                     $cookies[(string) SMART_FRAMEWORK_UNIQUE_ID_COOKIE_NAME] = (string) SMART_APP_VISITOR_COOKIE;
                                     // this is a requirement
                                 }
                                 //end if
                                 //--
                             }
                             //end if
                         }
                         //end if
                     }
                     //end if
                     //-- #end# sync
                     if ((string) SmartAuth::get_login_method() == 'HTTP-BASIC' and (string) $auth_name == '' and (string) $auth_pass == '' and strpos($tmp_current_script, '/admin.php') !== false and strpos($tmp_test_url_arr['scriptname'], '/admin.php') !== false) {
                         //--
                         if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                             $tmp_extra_log .= '[EXTRA]: HTTP-BASIC Auth method detected / Allowed to pass the Credentials - as the browsed URL belongs to this ADMIN Server as I run, the Auth credentials are set but passed as empty - everything seems to be safe I will send my credentials: USERNAME = \'' . SmartAuth::get_login_id() . '\' ; PASS = *****' . "\n";
                         }
                         //end if
                         //--
                         $auth_name = (string) SmartAuth::get_login_id();
                         $auth_pass = (string) SmartAuth::get_login_password();
                         //--
                     }
                     //end if
                     //--
                 } else {
                     //--
                     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                         $tmp_extra_log .= '[EXTRA]: Seems that the scripts are NOT identical :: ' . 'Current Script is: \'' . $tmp_current_script . '\' / Browsed Script is: \'' . $tmp_test_url_arr['scriptname'] . '\' !' . "\n";
                         $tmp_extra_log .= '[EXTRA]: This is the diff for having a comparation: ' . substr($tmp_current_path, 0, strlen($tmp_current_script)) . "\n";
                     }
                     //end if
                     //--
                 }
                 //end if
                 //--
             }
             //end if
             //--
         }
         //end if
         //--
         $browser->cookies = (array) $cookies;
         //--
         $data = (array) $browser->browse_url($y_url_or_path, $y_method, $y_ssl_method, $auth_name, $auth_pass);
         // do browse
         //--
         return array('log' => (string) $data['log'] . $tmp_extra_log, 'mode' => (string) $data['mode'], 'result' => (string) $data['result'], 'code' => (string) $data['code'], 'headers' => (string) $data['headers'], 'content' => (string) $data['content'], 'debuglog' => (string) $data['debuglog']);
         //--
     }
     //end if else
     //--
 }
 /**
  * this is the Magic Call Method
  *
  * @access 		private
  * @internal
  *
  */
 public function __call($method, array $args)
 {
     //--
     if ($this->err !== false) {
         if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
             Smart::log_notice('#REDIS-DB# :: Method Call Aborted. Detected Previous Redis Error before calling the method: ' . $method . '()');
         }
         //end if
         return null;
     }
     //end if
     //--
     $method = strtoupper((string) $method);
     $args = (array) $args;
     //--
     switch ((string) $method) {
         //--
         case 'MULTI':
             // start transaction
         // start transaction
         case 'EXEC':
             // commit transaction
         // commit transaction
         case 'DISCARD':
             // discard transaction
             //--
         // discard transaction
         //--
         case 'EXISTS':
             // determine if a key exists ; returns 1 if the key exists or 0 if does not exists
         // determine if a key exists ; returns 1 if the key exists or 0 if does not exists
         case 'TYPE':
             // determine the type of the given key
         // determine the type of the given key
         case 'STRLEN':
             // gets the strlen of a key
             //--
         // gets the strlen of a key
         //--
         case 'TTL':
             // get the TTL in seconds for a key ; -1 if the key does not expire ; -2 if the key does not exists
         // get the TTL in seconds for a key ; -1 if the key does not expire ; -2 if the key does not exists
         case 'EXPIRE':
             // set the expire time for a key in seconds ; returns 1 on success or 0 on failure
         // set the expire time for a key in seconds ; returns 1 on success or 0 on failure
         case 'EXPIREAT':
             // like EXPIRE but instead of set how many seconds to persist it sets the unix timestamp when will expire
         // like EXPIRE but instead of set how many seconds to persist it sets the unix timestamp when will expire
         case 'PERSIST':
             // remove the existing expiration timeout on key
             //--
         // remove the existing expiration timeout on key
         //--
         case 'GET':
             // get a key value ; returns the key value or null
         // get a key value ; returns the key value or null
         case 'SET':
             // set a key with a value ; returns OK if successful
         // set a key with a value ; returns OK if successful
         case 'APPEND':
             // append a value to an existing key value
         // append a value to an existing key value
         case 'DEL':
             // delete a key ; a key is ignored if does not exists ; return (integer) the number of keys that have been deleted
             //--
         // delete a key ; a key is ignored if does not exists ; return (integer) the number of keys that have been deleted
         //--
         case 'RENAME':
             // renames key to newkey ; returns an error when the source and destination names are the same, or when key does not exist
         // renames key to newkey ; returns an error when the source and destination names are the same, or when key does not exist
         case 'MOVE':
             // move a key to the given DB ; returns 1 on success or 0 on failure
             //--
         // move a key to the given DB ; returns 1 on success or 0 on failure
         //--
         case 'INCR':
             // increments a key that have an integer value with 1 ; max is 64-bit int ; if the value is non integer returns error ; returns the value after increment
         // increments a key that have an integer value with 1 ; max is 64-bit int ; if the value is non integer returns error ; returns the value after increment
         case 'INCRBY':
             // increments a key that have an integer value with the given int value ; max is 64-bit int ; if the value is non integer returns error ; returns the value after increment
         // increments a key that have an integer value with the given int value ; max is 64-bit int ; if the value is non integer returns error ; returns the value after increment
         case 'DECR':
             // decrements a key that have an integer value with 1 ; max is 64-bit int ; if the value is non integer returns error ; returns the value after decrement
         // decrements a key that have an integer value with 1 ; max is 64-bit int ; if the value is non integer returns error ; returns the value after decrement
         case 'DECRBY':
             // decrements a key that have an integer value with the given int value ; max is 64-bit int ; if the value is non integer returns error ; returns the value after decrement
             //--
         // decrements a key that have an integer value with the given int value ; max is 64-bit int ; if the value is non integer returns error ; returns the value after decrement
         //--
         case 'KEYS':
             // return all keys matching a pattern
         // return all keys matching a pattern
         case 'SCAN':
             // available since Redis 2.8 ; incrementally iterate over a collection of keys
         // available since Redis 2.8 ; incrementally iterate over a collection of keys
         case 'SORT':
             // sort key by pattern ; SORT mylist DESC ; SORT mylist ALPHA ; for UTF-8 the !LC_COLLATE environment must be set
         // sort key by pattern ; SORT mylist DESC ; SORT mylist ALPHA ; for UTF-8 the !LC_COLLATE environment must be set
         case 'RANDOMKEY':
             // return a random key from the currently selected database
             //--
         // return a random key from the currently selected database
         //--
         case 'HSET':
             // sets field in the hash stored at key to value
         // sets field in the hash stored at key to value
         case 'HDEL':
             // removes the specified fields from the hash stored at key
         // removes the specified fields from the hash stored at key
         case 'HEXISTS':
             // returns if field is an existing field in the hash stored at key
         // returns if field is an existing field in the hash stored at key
         case 'HGET':
             // returns the value associated with field in the hash stored at key
         // returns the value associated with field in the hash stored at key
         case 'HGETALL':
             // returns all fields and values of the hash stored at key
         // returns all fields and values of the hash stored at key
         case 'HINCRBY':
             // increments the number stored at field in the hash stored at key by increment ; if key does not exist, a new key holding a hash is created
         // increments the number stored at field in the hash stored at key by increment ; if key does not exist, a new key holding a hash is created
         case 'HINCRBYFLOAT':
             // increment the specified field of an hash stored at key, and representing a floating point number, by the specified increment
         // increment the specified field of an hash stored at key, and representing a floating point number, by the specified increment
         case 'HKEYS':
             // returns all field names in the hash stored at key
         // returns all field names in the hash stored at key
         case 'HLEN':
             // returns the number of fields contained in the hash stored at key
         // returns the number of fields contained in the hash stored at key
         case 'HMGET':
             // returns the values associated with the specified fields in the hash stored at key
         // returns the values associated with the specified fields in the hash stored at key
         case 'HMSET':
             // sets the specified fields to their respective values in the hash stored at key
         // sets the specified fields to their respective values in the hash stored at key
         case 'HSCAN':
             // available since 2.8.0 ; iterates fields of Hash types and their associated values
         // available since 2.8.0 ; iterates fields of Hash types and their associated values
         case 'HSET':
             // sets field in the hash stored at key to value ; if key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten
         // sets field in the hash stored at key to value ; if key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten
         case 'HSETNX':
             // sets field in the hash stored at key to value, only if field does not yet exist
         // sets field in the hash stored at key to value, only if field does not yet exist
         case 'HSTRLEN':
             // returns the string length of the value associated with field in the hash stored at key
         // returns the string length of the value associated with field in the hash stored at key
         case 'HVALS':
             // returns all values in the hash stored at key
             //--
         // returns all values in the hash stored at key
         //--
         case 'LINSERT':
             // inserts value in the list stored at key either before or after the reference value pivot
         // inserts value in the list stored at key either before or after the reference value pivot
         case 'LINDEX':
             // returns the element at index 0..n in the list stored at key
         // returns the element at index 0..n in the list stored at key
         case 'LLEN':
             // returns the length of the list stored at key ; if key does not exist, it is interpreted as an empty list and 0 is returned ; an error is returned when the value stored at key is not a list
         // returns the length of the list stored at key ; if key does not exist, it is interpreted as an empty list and 0 is returned ; an error is returned when the value stored at key is not a list
         case 'LPOP':
             // removes and returns the first element of the list stored at key
         // removes and returns the first element of the list stored at key
         case 'RPOP':
             // removes and returns the last element of the list stored at key
         // removes and returns the last element of the list stored at key
         case 'LPUSH':
             // insert all the specified values at the begining of the list stored at key ; key value
         // insert all the specified values at the begining of the list stored at key ; key value
         case 'LPUSHX':
             // inserts value at the head of the list stored at key, only if key already exists and holds a list. In contrary to LPUSH, no operation will be performed when key does not yet exist
         // inserts value at the head of the list stored at key, only if key already exists and holds a list. In contrary to LPUSH, no operation will be performed when key does not yet exist
         case 'RPUSH':
             // insert all the specified values at the end of the list stored at key ; key value
         // insert all the specified values at the end of the list stored at key ; key value
         case 'RPUSHX':
             // inserts value at the tail of the list stored at key, only if key already exists and holds a list. In contrary to RPUSH, no operation will be performed when key does not yet exist
         // inserts value at the tail of the list stored at key, only if key already exists and holds a list. In contrary to RPUSH, no operation will be performed when key does not yet exist
         case 'RPOPLPUSH':
             // atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination
         // atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination
         case 'LRANGE':
             // get a list key value(s) ; key start stop
         // get a list key value(s) ; key start stop
         case 'LREM':
             // remove list key(s) ; key count value ; count > 0: Remove elements equal to value moving from head to tail ; count < 0: Remove elements equal to value moving from tail to head ; count = 0: Remove all elements equal to value
         // remove list key(s) ; key count value ; count > 0: Remove elements equal to value moving from head to tail ; count < 0: Remove elements equal to value moving from tail to head ; count = 0: Remove all elements equal to value
         case 'LSET':
             // set a list key value ; key index value
         // set a list key value ; key index value
         case 'LTRIM':
             // trim an existing list so that it will contain only the specified range of elements specified ; key start stop
             //--
         // trim an existing list so that it will contain only the specified range of elements specified ; key start stop
         //--
         case 'SADD':
             // add a key to a set
         // add a key to a set
         case 'SREM':
             // remove a key from a set
         // remove a key from a set
         case 'SMOVE':
             // atomically move member from the set at source to the set at destination
         // atomically move member from the set at source to the set at destination
         case 'SCARD':
             // returns the cardinality of a key
         // returns the cardinality of a key
         case 'SDIFF':
             // returns the difference between the first set and all the successive sets
         // returns the difference between the first set and all the successive sets
         case 'SDIFFSTORE':
             // identical with SDIFF but instead of return will store the result
         // identical with SDIFF but instead of return will store the result
         case 'SINTER':
             // returns the intersection of all the given sets
         // returns the intersection of all the given sets
         case 'SINTERSTORE':
             // identical with SINTER but instead of return will store the result
         // identical with SINTER but instead of return will store the result
         case 'SUNION':
             // returns the members of the set resulting from the union of all the given sets
         // returns the members of the set resulting from the union of all the given sets
         case 'SUNIONSTORE':
             // identical with SUNION but instead of return will store the result
         // identical with SUNION but instead of return will store the result
         case 'SISMEMBER':
             // returns if member is a member of the set stored at key
         // returns if member is a member of the set stored at key
         case 'SMEMBERS':
             // returns all the members of the set value stored at key
         // returns all the members of the set value stored at key
         case 'SPOP':
             // removes and returns one or more random elements from the set value store at key
         // removes and returns one or more random elements from the set value store at key
         case 'SRANDMEMBER':
             // when called with just the key argument, return a random element from the set value stored at key ; since Redis 2.6 a second count parameter has been added
         // when called with just the key argument, return a random element from the set value stored at key ; since Redis 2.6 a second count parameter has been added
         case 'SSCAN':
             // available since Redis 2.8 ; incrementally iterate over a collection of elements in a set
             //--
         // available since Redis 2.8 ; incrementally iterate over a collection of elements in a set
         //--
         case 'ZADD':
             // adds all the specified members with the specified scores to the sorted set stored at key
         // adds all the specified members with the specified scores to the sorted set stored at key
         case 'ZREM':
             // removes the specified members from the sorted set stored at key ; non existing members are ignored
         // removes the specified members from the sorted set stored at key ; non existing members are ignored
         case 'ZCARD':
             // returns the sorted set cardinality (number of elements) of the sorted set stored at key
         // returns the sorted set cardinality (number of elements) of the sorted set stored at key
         case 'ZCOUNT':
             // returns the number of elements in the sorted set at key with a score between min and max
         // returns the number of elements in the sorted set at key with a score between min and max
         case 'ZINCRBY':
             // increments the score of member in the sorted set stored at key by increment
         // increments the score of member in the sorted set stored at key by increment
         case 'ZINTERSTORE':
             // computes the intersection of numkeys sorted sets given by the specified keys, and stores the result in destination
         // computes the intersection of numkeys sorted sets given by the specified keys, and stores the result in destination
         case 'ZRANGE':
             // returns the specified range of elements in the sorted set stored at key
         // returns the specified range of elements in the sorted set stored at key
         case 'ZRANGEBYSCORE':
             // returns all the elements in the sorted set at key with a score between min and max (including elements with score equal to min or max)
         // returns all the elements in the sorted set at key with a score between min and max (including elements with score equal to min or max)
         case 'ZRANK':
             // returns the rank of member in the sorted set stored at key, with the scores ordered from low to high
         // returns the rank of member in the sorted set stored at key, with the scores ordered from low to high
         case 'ZREMRANGEBYSCORE':
             // removes all elements in the sorted set stored at key with a score between min and max (inclusive)
         // removes all elements in the sorted set stored at key with a score between min and max (inclusive)
         case 'ZREVRANGE':
             // returns the specified range of elements in the sorted set stored at key
         // returns the specified range of elements in the sorted set stored at key
         case 'ZREVRANGEBYSCORE':
             // returns all the elements in the sorted set at key with a score between max and min (including elements with score equal to max or min)
         // returns all the elements in the sorted set at key with a score between max and min (including elements with score equal to max or min)
         case 'ZREVRANK':
             // returns the rank of member in the sorted set stored at key, with the scores ordered from high to low
         // returns the rank of member in the sorted set stored at key, with the scores ordered from high to low
         case 'ZSCORE':
             // returns the score of member in the sorted set at key
         // returns the score of member in the sorted set at key
         case 'ZUNIONSTORE':
             // computes the union of numkeys sorted sets given by the specified keys, and stores the result in destination
         // computes the union of numkeys sorted sets given by the specified keys, and stores the result in destination
         case 'ZSCAN':
             // available since 2.8.0 ; iterates elements of Sorted Set types and their associated scores
             //--
         // available since 2.8.0 ; iterates elements of Sorted Set types and their associated scores
         //--
         case 'SAVE':
             // synchronous save the DB to disk ; returns OK on success
         // synchronous save the DB to disk ; returns OK on success
         case 'FLUSHDB':
             // remove all keys from the selected database
         // remove all keys from the selected database
         case 'FLUSHALL':
             // remove all keys from all databases
         // remove all keys from all databases
         case 'DBSIZE':
             // return the number of keys in the currently-selected database
             //--
         // return the number of keys in the currently-selected database
         //--
         case 'INFO':
             // returns information and statistics about the server
         // returns information and statistics about the server
         case 'TIME':
             // returns the current server time as a two items lists: a Unix timestamp and the amount of microseconds already elapsed in the current second
             //--
         // returns the current server time as a two items lists: a Unix timestamp and the amount of microseconds already elapsed in the current second
         //--
         case 'ECHO':
             // echo a message
         // echo a message
         case 'PING':
             // ping the server ; returns PONG
         // ping the server ; returns PONG
         case 'QUIT':
             // always return OK ; ask the server to close the connection ; the connection is closed as soon as all pending replies have been written to the client
             //--
             if (!is_resource($this->connect())) {
                 // this have it's own error raise mechanism
                 if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                     Smart::log_notice('#REDIS-DB# :: Redis connection FAILED just before calling the method: ' . $method . '()');
                 }
                 //end if
                 return null;
             }
             //end if
             //--
             return $this->run_command($method, $args);
             //--
             break;
         case 'AUTH':
             // password ; returns OK
         // password ; returns OK
         case 'SELECT':
             // select the DB by the given index (default is 0 .. 15)
             //--
             $this->error(true, 'Redis Dissalowed Command', 'Method is Forbidden', 'Method: ' . $method);
             // fatal error
             return null;
             //--
         //--
         default:
             //--
             $this->error(true, 'Redis Unavailable Command', 'Method is Unavailable', 'Method: ' . $method);
             // fatal error
             return null;
             //--
     }
     //end switch
     //--
 }
 /**
  * Force Instant Flush Output (ONLY for controllers that do a direct output ... SMART_APP_MODULE_DIRECT_OUTPUT must be set to TRUE).
  * This will do instant flush and also ob_flush if necessary and detected (for example when the output_buffering is enabled in PHP.INI).
  * NOTICE: be careful using this function to avoid break intermediary output bufferings !!
  *
  * @access 		private
  * @internal
  *
  * @return -						:: This function does not return anything
  */
 public final function InstantFlush()
 {
     //--
     if (SMART_APP_MODULE_DIRECT_OUTPUT !== true) {
         Smart::log_notice('Using the InstantFlush() in controllers that are not using direct output is not allowed as will break the middleware output chain ...');
         return;
     }
     //end if
     //--
     $output_buffering_status = (array) @ob_get_status();
     //-- type: 0 = PHP_OUTPUT_HANDLER_INTERNAL ; 1 = PHP_OUTPUT_HANDLER_USER
     if ((string) $output_buffering_status['type'] == '0' and $output_buffering_status['chunk_size'] > 0) {
         // avoid to break user level output buffering(s), so enable this just for level zero (internal, if set in php.ini)
         @ob_flush();
     }
     //end if
     //--
     @flush();
     //--
 }
 public function transform($xml_str, $log_parse_err_warns = false)
 {
     //--
     $xml_str = (string) trim((string) $xml_str);
     if ((string) $xml_str == '') {
         return array();
     }
     //end if
     //--
     @libxml_use_internal_errors(true);
     @libxml_clear_errors();
     //--
     $arr = $this->SimpleXML2Array(@simplexml_load_string($this->FixXmlRoot((string) $xml_str), 'SimpleXMLElement', LIBXML_ERR_WARNING | LIBXML_NONET | LIBXML_PARSEHUGE | LIBXML_BIGLINES | LIBXML_NOCDATA));
     //-- log errors if any
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes' or $log_parse_err_warns === true) {
         // log errors if set :: OR (Smart::array_size($arr) <= 0)
         $errors = (array) @libxml_get_errors();
         if (Smart::array_size($errors) > 0) {
             $notice_log = '';
             foreach ($errors as $z => $error) {
                 if (is_object($error)) {
                     $notice_log .= 'PARSE-ERROR: [' . $the_ercode . '] / Level: ' . $error->level . ' / Line: ' . $error->line . ' / Column: ' . $error->column . ' / Code: ' . $error->code . ' / Message: ' . $error->message . "\n";
                 }
                 //end if
             }
             //end foreach
             if ((string) $notice_log != '') {
                 Smart::log_notice('SmartXmlParser NOTICE [SimpleXML / Encoding: ' . $this->encoding . ']:' . "\n" . $notice_log . "\n" . '#END' . "\n");
             }
             //end if
             if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
                 Smart::log_notice('SmartXmlParser / Debug XML-String:' . "\n" . $xml_str . "\n" . '#END');
             }
             //end if
         }
         //end if
     }
     //end if
     //--
     @libxml_clear_errors();
     @libxml_use_internal_errors(false);
     //--
     if (Smart::array_size($arr) <= 0) {
         $arr = array('XML@PARSER:ERROR' => 'SmartXmlParser / No XML Data or Invalid Data');
         // in case of error, return this
     }
     //end if
     //--
     return (array) $arr;
     //--
 }
 public function browse_url($url, $method = 'GET', $ssl_version = '', $user = '', $pwd = '', $proxy = array())
 {
     //-- reset
     $this->reset();
     //--
     //--
     if ($this->debug) {
         $run_time = microtime(true);
     }
     //end if
     //--
     //--
     $this->connect_timeout = (int) $this->connect_timeout;
     if ($this->connect_timeout < 1) {
         $this->connect_timeout = 1;
     }
     //end if
     if ($this->connect_timeout > 120) {
         $this->connect_timeout = 120;
     }
     //end if
     //--
     $this->exec_timeout = (int) $this->exec_timeout;
     if ($this->exec_timeout > 0) {
         if ($this->exec_timeout < 30) {
             $this->exec_timeout = 30;
         }
         //end if
         if ($this->exec_timeout > 300) {
             $this->exec_timeout = 300;
         }
         //end if
     } else {
         $this->exec_timeout = 0;
     }
     //end if else
     //--
     //--
     $this->status = 999;
     //--
     //-- log action
     if ($this->debug) {
         $this->log .= '[INF] CURL HTTP(S)/FTP Robot Browser :: Browse :: url \'' . $url . '\' @ Auth-User: '******' // Auth-Pass-Length: (' . strlen($pwd) . ') // Method: ' . $method . ' // SSLVersion: ' . $ssl_version . "\n";
         $this->log .= '[INF] CURL Protocol: ' . $this->protocol . "\n";
         $this->log .= '[INF] Connection TimeOut: ' . $this->connect_timeout . "\n";
         $this->log .= '[INF] Execution TimeOut: ' . $this->exec_timeout . "\n";
     }
     //end if
     //--
     //-- method
     $this->method = (string) strtoupper(trim((string) $method));
     //--
     //-- separations
     $this->url_parts = (array) Smart::separe_url_parts($url);
     $protocol = (string) $this->url_parts['protocol'];
     $server = (string) $this->url_parts['server'];
     $port = (string) $this->url_parts['port'];
     $path = (string) $this->url_parts['path'];
     //--
     if ($this->debug) {
         $this->log .= '[INF] Analize of the URL: ' . @print_r($this->url_parts, 1) . "\n";
     }
     //end if
     //--
     $is_ftp = false;
     $use_ssl_tls = false;
     switch ((string) $protocol) {
         case 'http://':
             break;
         case 'https://':
             $use_ssl_tls = true;
             break;
         case 'ftp://':
             $is_ftp = true;
             break;
         case 'ftps://':
             $is_ftp = true;
             $use_ssl_tls = true;
             break;
         default:
             //--
             if ($this->debug) {
                 $this->log .= '[ERR] Unsupported URL Type: [' . $protocol . '] for URL: ' . $url . "\n";
             }
             //end if
             //--
             Smart::log_warning('LibCurlHttp(s)Ftp // GetFromURL () // Unsupported URL Type: [' . $protocol . '] for URL: ' . $url);
             //--
             return (array) $this->answer(0, $url, $ssl_version, $user);
             //--
     }
     //end switch
     //--
     //--
     if (!function_exists('curl_init')) {
         //--
         if ($this->debug) {
             $this->log .= '[ERR] PHP CURL Extension is missing' . "\n";
         }
         //end if
         //--
         Smart::log_warning('LibCurlHttp(s)Ftp // GetFromURL () // CURL Extension is missing ...');
         //--
         return (array) $this->answer(0, $url, $ssl_version, $user);
         //--
     }
     //end if
     //--
     //--
     $this->curl = @curl_init();
     // Initialise a cURL handle
     //--
     if (!$this->curl) {
         //--
         if ($this->debug) {
             $this->log .= '[ERR] PHP CURL Init Failed' . "\n";
         }
         //end if
         //--
         Smart::log_warning('LibCurlHttp(s)Ftp // GetFromURL () // CURL Init Failed ...');
         //--
         return (array) $this->answer(0, $url, $ssl_version, $user);
         //--
     }
     //end if
     //--
     if (Smart::array_size($this->rawheaders) > 0) {
         foreach ($this->rawheaders as $key => $val) {
             $this->raw_headers[] = (string) $key . ': ' . $val;
         }
         //end foreach
     }
     //end if
     //-- set allowed protocols: HTTP / HTTPS / FTP / FTPS
     @curl_setopt($this->curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | CURLPROTO_FTPS);
     //--
     //-- set user agent
     @curl_setopt($this->curl, CURLOPT_USERAGENT, (string) $this->useragent);
     //--
     //-- timeouts
     @curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, (int) $this->connect_timeout);
     if ($this->exec_timeout > 0) {
         @curl_setopt($this->curl, CURLOPT_TIMEOUT, (int) $this->exec_timeout);
     }
     //end if
     //--
     //-- protocol
     if ((string) $this->protocol == '1.1') {
         $this->raw_headers[] = (string) 'Connection: close';
         @curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
     } else {
         // 1.0
         @curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
     }
     //end if else
     //--
     //-- proxy
     $is_using_proxy = false;
     if (Smart::array_size($proxy) > 0) {
         // If the $proxy variable is set, then use: $proxy['ip:port'] ; $proxy['type'] ; $proxy['auth-user'] ; $proxy['auth-pass']
         //--
         if ((string) $proxy['ip:port'] != '') {
             //--
             $pxy_type = '';
             switch ((string) strtoupper(trim((string) $proxy['type']))) {
                 case 'SOCKS4':
                     $is_using_proxy = true;
                     $pxy_type = CURLPROXY_SOCKS4;
                     break;
                 case 'SOCKS4A':
                     $is_using_proxy = true;
                     $pxy_type = CURLPROXY_SOCKS4A;
                     break;
                 case 'SOCKS5':
                     $is_using_proxy = true;
                     $pxy_type = CURLPROXY_SOCKS5;
                     break;
                 case 'SOCKS5H':
                     $is_using_proxy = true;
                     $pxy_type = CURLPROXY_SOCKS5_HOSTNAME;
                     break;
                 case 'HTTP':
                 default:
                     if ($is_ftp) {
                         $proxy['type'] = 'N/A';
                     } else {
                         $is_using_proxy = true;
                         $proxy['type'] = 'HTTP';
                     }
                     //end if
                     $pxy_type = CURLPROXY_HTTP;
             }
             //end switch
             //--
             if ($is_using_proxy) {
                 //--
                 if ($this->debug) {
                     $this->log .= '[INF] Using Proxy: ' . $proxy['ip:port'] . ' [Type: ' . $proxy['type'] . ']' . "\n";
                 }
                 //end if
                 //--
                 $this->cproxy = (array) $proxy;
                 if ((string) $this->cproxy['auth-pass'] != '') {
                     $this->cproxy['auth-pass'] = '******' . strlen($proxy['auth-pass']) . ') *****';
                 }
                 //end if
                 //--
                 @curl_setopt($this->curl, CURLOPT_PROXY, (string) $proxy['ip:port']);
                 @curl_setopt($this->curl, CURLOPT_PROXYTYPE, $pxy_type);
                 //--
                 if ((string) $proxy['auth-user'] != '') {
                     //--
                     if ($this->debug) {
                         $this->log .= '[INF] Proxy Authentication will be attempted for USERNAME = \'' . $proxy['auth-user'] . '\' ; PASSWORD(' . strlen($proxy['auth-pass']) . ') *****' . "\n";
                     }
                     //end if
                     //--
                     @curl_setopt($this->curl, CURLOPT_PROXYUSERPWD, (string) $proxy['auth-user'] . ':' . $proxy['auth-pass']);
                     //@curl_setopt($this->curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); // this does not work at all, thus let CURL choose ...: CURLAUTH_BASIC | CURLAUTH_DIGEST
                     //--
                 }
                 //end if
                 //--
             }
             //end if
             //--
         }
         //end if
         //--
     }
     //end if
     //--
     //-- auth
     if ((string) $user != '') {
         //--
         if ($this->debug) {
             $this->log .= '[INF] Authentication will be attempted for USERNAME = \'' . $user . '\' ; PASSWORD(' . strlen($pwd) . ') *****' . "\n";
         }
         //end if
         //-- $this->raw_headers[] = 'Authorization: Basic '.base64_encode($user.':'.$pwd); // it is better to use as below as it can handle more auth types :-)
         @curl_setopt($this->curl, CURLOPT_USERPWD, (string) $user . ':' . $pwd);
         //@curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); // this does not work at all, thus let CURL choose ...: CURLAUTH_BASIC | CURLAUTH_DIGEST
         //--
     }
     //end if
     //--
     //-- SSL/TLS Options
     $browser_protocol = '';
     //--
     if ($use_ssl_tls) {
         //--
         if (!function_exists('openssl_open')) {
             //--
             if ($this->debug) {
                 $this->log .= '[ERR] PHP OpenSSL Extension is required to perform SSL requests' . "\n";
             }
             //end if
             //--
             Smart::log_warning('LibCurlHttp(s)Ftp // GetFromURL (' . $browser_protocol . $server . ':' . $port . $path . ') // PHP OpenSSL Extension not installed ...');
             //--
             return (array) $this->answer(0, $url, $ssl_version, $user);
             //--
         }
         //end if
         //--
         switch (strtolower((string) $ssl_version)) {
             case 'ssl':
                 $browser_protocol = CURL_SSLVERSION_DEFAULT;
                 // default SSL
                 break;
             case 'sslv3':
                 $browser_protocol = CURL_SSLVERSION_SSLv3;
                 // SSLv3
                 break;
             case 'tls':
             default:
                 $browser_protocol = CURL_SSLVERSION_TLSv1;
                 // TLSv1.x
         }
         //end switch
         //--
         @curl_setopt($this->curl, CURLOPT_SSLVERSION, $browser_protocol);
         //--
         if (defined('SMART_FRAMEWORK_SSL_CA_PATH')) {
             if ((string) SMART_FRAMEWORK_SSL_CA_PATH != '') {
                 @curl_setopt($this->curl, CURLOPT_CAPATH, Smart::real_path((string) SMART_FRAMEWORK_SSL_CA_PATH));
             }
             //end if
         }
         //end if
         @curl_setopt($this->curl, CURLOPT_SSL_CIPHER_LIST, (string) SMART_FRAMEWORK_SSL_CIPHERS);
         @curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, (bool) SMART_FRAMEWORK_SSL_VFY_PEER_NAME);
         // FIX: use vfy peer name instead of SMART_FRAMEWORK_SSL_VFY_HOST as there is no fine tunning here ...
         @curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, (bool) SMART_FRAMEWORK_SSL_VFY_PEER);
         // (bool)SMART_FRAMEWORK_SSL_VFY_PEER_NAME 		:: CURL is missing the option to specific allow/dissalow the peer name (allow also wildcard names *)
         // (bool)SMART_FRAMEWORK_SSL_ALLOW_SELF_SIGNED 	:: CURL is missing the option to specific allow/disallow self-signed certificates but verified above
         // (bool)SMART_FRAMEWORK_SSL_DISABLE_COMPRESS 	:: CURL is missing the option to disable SSL/TLS compression (help mitigate the CRIME attack vector)
         //--
     }
     //end if
     //--
     //-- other cURL options that are required
     @curl_setopt($this->curl, CURLOPT_HEADER, true);
     @curl_setopt($this->curl, CURLOPT_COOKIESESSION, true);
     @curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);
     @curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
     //--
     //--
     if (Smart::array_size($this->cookies) > 0) {
         $send_cookies = '';
         foreach ($this->cookies as $key => $value) {
             if ((string) $key != '') {
                 if ((string) $value != '') {
                     $send_cookies .= (string) SmartHttpUtils::encode_var_cookie($key, $value);
                 }
                 //end if
             }
             //end if
         }
         //end foreach
         if ((string) $send_cookies != '') {
             $this->raw_headers[] = (string) 'Cookie: ' . $send_cookies;
         }
         //end if
         $send_cookies = '';
     }
     //end if
     //--
     $have_post_vars = false;
     if (Smart::array_size($this->postvars) > 0) {
         $post_string = '';
         foreach ((array) $this->postvars as $key => $val) {
             $post_string .= (string) SmartHttpUtils::encode_var_post($key, $val);
         }
         //end foreach
         if ((string) $post_string != '') {
             if ((string) $this->method == 'GET') {
                 $this->method = 'POST';
             }
             //end if
             $have_post_vars = true;
             @curl_setopt($this->curl, CURLOPT_POSTFIELDS, (string) $post_string);
         }
         //end if
         $post_string = '';
     } elseif ((string) $this->poststring != '') {
         if ((string) $this->method == 'GET') {
             $this->method = 'POST';
         }
         //end if
         $have_post_vars = true;
         @curl_setopt($this->curl, CURLOPT_POSTFIELDS, (string) $this->poststring);
     } elseif ((string) $this->jsonrequest != '') {
         $this->raw_headers[] = 'Content-Type: application/json';
         $this->raw_headers[] = 'Content-Length: ' . strlen($this->jsonrequest);
     } elseif ((string) $this->xmlrequest != '') {
         $this->raw_headers[] = 'Content-Type: application/xml';
         $this->raw_headers[] = 'Content-Length: ' . strlen($this->xmlrequest);
     }
     //end if else
     //--
     switch ((string) $this->method) {
         case 'GET':
             break;
         case 'POST':
             if ($have_post_vars) {
                 @curl_setopt($this->curl, CURLOPT_POST, true);
             }
             //end if
             break;
         case 'HEAD':
         case 'PUT':
         case 'DELETE':
         default:
             if ($have_post_vars) {
                 @curl_setopt($this->curl, CURLOPT_POST, true);
             }
             //end if
             @curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, (string) $this->method);
     }
     //end switch
     //--
     if (Smart::array_size($this->raw_headers) > 0) {
         // request headers are constructed above
         @curl_setopt($this->curl, CURLOPT_HTTPHEADER, (array) $this->raw_headers);
     }
     //end if
     //--
     //-- Execute a Curl request
     @curl_setopt($this->curl, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
     @curl_setopt($this->curl, CURLOPT_FRESH_CONNECT, true);
     @curl_setopt($this->curl, CURLOPT_FORBID_REUSE, true);
     @curl_setopt($this->curl, CURLOPT_URL, (string) $url);
     //--
     if (!$this->curl) {
         //--
         if ($this->debug) {
             $this->log .= '[ERR] CURL Aborted before Execution' . "\n";
         }
         //end if
         //--
         Smart::log_warning('LibCurlHttp(s)Ftp // GetFromURL () // CURL Aborted before Execution ...');
         //--
         return (array) $this->answer(0, $url, $ssl_version, $user);
         //--
     }
     //end if
     //--
     $results = @curl_exec($this->curl);
     $error = @curl_errno($this->curl);
     //--
     //-- eval results
     $bw_info = array();
     $is_ok = 0;
     //--
     if ($results) {
         //--
         $is_ok = 1;
         //--
         $bw_info = (array) @curl_getinfo($this->curl);
         //--
         if ($is_ftp) {
             //--
             $this->header = 'CURL Browser :: FTP(s) have no headers ...';
             $this->body = (string) $results;
             //--
         } else {
             // http
             //--
             $hd_len = (int) $bw_info['header_size'];
             // get header length
             //--
             if ($hd_len > 0) {
                 //--
                 $this->header = (string) substr((string) $results, 0, $hd_len);
                 $this->body = (string) substr((string) $results, $hd_len);
                 //--
             } else {
                 //--
                 $this->header = (string) $results;
                 $this->body = '';
                 //--
                 $is_ok = 0;
                 //--
                 if ($this->debug) {
                     Smart::log_notice('LibCurlHttp(s)Ftp // GetFromURL () // CURL Execution Failed to Separe HTTP Header from Body. Reported (invalid) Header size is: [' . $hd_len . ']');
                     $this->log .= '[ERR] CURL Execution Failed to Separe HTTP Header from Body. Invalid Header size: [' . $hd_len . ']' . "\n";
                 }
                 //end if
                 //--
             }
             //end if else
             //--
         }
         //end if else
         //--
         $results = '';
         // free memory
         //--
         $is_unauth = false;
         if ((string) $bw_info['http_code'] == '401') {
             //--
             $is_unauth = true;
             //--
             if ($this->debug) {
                 if ((string) $user != '') {
                     $this->log .= '[ERR] HTTP Authentication Failed for URL: [User='******']: ' . $url . "\n";
                     Smart::log_notice('LibCurlHttp(s)Ftp // GetFromURL // HTTP Authentication Failed for URL: [User='******']: ' . $url);
                 } else {
                     $this->log .= '[ERR] HTTP Authentication is Required for URL: ' . $url . "\n";
                     Smart::log_notice('LibCurlHttp(s)Ftp // GetFromURL // HTTP Authentication is Required for URL: ' . $url);
                 }
                 //end if
             }
             //end if
             //--
         }
         //end if
         //--
         if ($is_unauth and $this->no_content_stop_if_unauth) {
             //--
             $this->body = '';
             // in this case (by settings) no content (response body) should be returned
             //--
         }
         //end if
         //--
         if ($error) {
             //--
             $is_ok = 0;
             //--
             if ($this->debug) {
                 $this->log .= '[ERR] CURL Execution Reported some Errors. ErrorCode: [' . $error . ']' . "\n";
                 Smart::log_notice('LibCurlHttp(s)Ftp // GetFromURL () // CURL Execution Reported some Errors. ErrorCode: [' . $error . ']');
             }
             //end if
             //--
         }
         //end if
         //--
         $this->status = (int) $bw_info['http_code'];
         //--
     } else {
         //--
         $is_ok = 0;
         //--
         $this->log .= '[ERR] CURL Returned No Results. ErrorCode: [' . $error . ']' . "\n";
         //--
     }
     //end if
     //--
     if ($is_unauth) {
         //--
         $is_ok = 0;
         //--
     }
     //end if
     //--
     //--
     $this->close_connection();
     //--
     //--
     if ($this->debug) {
         $run_time = microtime(true) - $run_time;
         $this->log .= '[INF] Total Time: ' . $run_time . ' sec.' . "\n";
     }
     //end if
     //--
     //--
     return (array) $this->answer($is_ok, $url, $ssl_version, $user, $bw_info);
     //--
 }