public static function captcha_image($y_form_name, $y_store, $y_mode = 'hashed', $y_pool = '0123456789', $y_noise = '200', $y_chars = '5', $y_width = '170', $y_height = '50', $y_format = 'png', $y_font_file = 'lib/core/plugins/fonts/liberation-mono-italic.ttf', $y_font_size = '24', $y_char_space = '20', $y_char_xvary = '20', $y_char_yvary = '10', $y_char_colors = array(0x111111, 0x333333, 0x778899, 0x666699, 0x3366, 0x669966, 0x6600, 0xff3300), $y_noise_colors = array(0x888888, 0x999999, 0xaaaaaa, 0xbbbbbb, 0xcccccc, 0xdddddd, 0xeeeeee, 0x8080c0))
 {
     //--
     $captcha = new SmartCaptchaImageDraw();
     //--
     $captcha->store = (string) $y_store;
     $captcha->format = (string) $y_format;
     $captcha->mode = (string) $y_mode;
     $captcha->pool = (string) $y_pool;
     $captcha->width = Smart::format_number_int($y_width, '+');
     $captcha->height = Smart::format_number_int($y_height, '+');
     $captcha->chars = Smart::format_number_int($y_chars, '+');
     $captcha->charfont = (string) $y_font_file;
     $captcha->charttfsize = Smart::format_number_int($y_font_size, '+');
     $captcha->charspace = Smart::format_number_int($y_char_space, '+');
     $captcha->charxvar = Smart::format_number_int($y_char_xvary, '+');
     $captcha->charyvar = Smart::format_number_int($y_char_yvary, '+');
     $captcha->noise = Smart::format_number_int($y_noise, '+');
     if (is_array($y_char_colors)) {
         $captcha->colors_chars = (array) $y_char_colors;
     }
     //end if
     if (is_array($y_noise_colors)) {
         $captcha->colors_noise = (array) $y_noise_colors;
     }
     //end if
     //--
     return $captcha->draw_image((string) $y_form_name);
     //--
 }
 /**
  * Provides a fixed length string text ; if longer than allowed length will add trailing dots (...)
  *
  * @param 	STRING 	$ystr 				:: The text string to be processed
  * @param 	STRING 	$ylen 				:: The fixed length of the string
  * @param 	BOOLEAN	$y_cut_words		:: if TRUE, will CUT last word to provide a fixed length ; if FALSE will eliminate unterminate last word ; default is TRUE
  *
  * @return 	STRING						:: The processed string (text)
  */
 public static function text_endpoints($ystr, $ylen, $y_cut_words = true, $y_dots = '...')
 {
     //--
     $ystr = (string) trim((string) $ystr);
     $ylen = Smart::format_number_int($ylen, '+');
     //--
     if ($ylen > 0 and SmartUnicode::str_len($ystr) > $ylen) {
         $ystr = (string) SmartUnicode::sub_str($ystr, 0, $ylen - 3);
         if (!$y_cut_words) {
             $ystr = (string) preg_replace('/\\s+?(\\S+)?$/', '', (string) $ystr);
         }
         //end if
         $ystr .= (string) $y_dots;
     }
     //end if
     //--
     return (string) $ystr;
     //--
 }
 private static function print_log_database($title, $db_log)
 {
     //--
     $log = '';
     //--
     $log .= '<div class="smartframework_debugbar_status smartframework_debugbar_status_head"><font size="4"><b>' . Smart::escape_html($title) . ' :: DATABASE Queries</b></font></div>';
     //--
     $max = Smart::array_size($db_log['log']);
     if (is_array($db_log) and $max > 0) {
         $log .= '<div class="smartframework_debugbar_status smartframework_debugbar_status_highlight" style="width:450px;">Total Queries Number: <b>' . Smart::escape_html(Smart::format_number_int($db_log['total-queries'], '+')) . '</b></div>';
         $log .= '<div class="smartframework_debugbar_status smartframework_debugbar_status_highlight" style="width:450px;">Total Queries Time: <b>' . Smart::escape_html(Smart::format_number_dec($db_log['total-time'], 9, '.', '')) . ' sec.' . '</b></div>';
         $num = 0;
         for ($i = 0; $i < $max; $i++) {
             //--
             $tmp_arr = (array) $db_log['log'][$i];
             //--
             switch ((string) $tmp_arr['type']) {
                 case 'transaction':
                     //--
                     $num++;
                     //--
                     $tmp_color = '#003399';
                     //--
                     $log .= '<div class="smartframework_debugbar_inforow" style="font-size:12px; color:' . $tmp_color . ';">';
                     $log .= $num . '. ' . '<b>' . Smart::escape_html($tmp_arr['data']) . '</b>';
                     if ((string) $tmp_arr['connection'] != '') {
                         $log .= ' @ ' . Smart::escape_html($tmp_arr['connection']);
                     }
                     //end if
                     if ($tmp_arr['time'] > 0) {
                         $log .= '<br><span style="padding:1px;"><b>@Time: ' . Smart::format_number_dec($tmp_arr['time'], 9, '.', '') . ' sec.</b></span>';
                     }
                     //end if
                     if ((string) $tmp_arr['query'] != '') {
                         $log .= '<br><span class="smartframework_debugbar_status_highlight" style="padding:1px;"><b>' . Smart::escape_html($tmp_arr['query']) . '</b></span>';
                     }
                     //end if
                     $log .= '</div>';
                     //--
                     break;
                 case 'set':
                 case 'count':
                 case 'read':
                 case 'write':
                 case 'nosql':
                     //--
                     if ((string) $tmp_arr['skip-count'] != 'yes') {
                         $num++;
                     }
                     //end if
                     //--
                     if ((string) $tmp_arr['type'] == 'write') {
                         $tmp_color = '#666699';
                     } elseif ((string) $tmp_arr['type'] == 'read') {
                         $tmp_color = '#333333';
                     } elseif ((string) $tmp_arr['type'] == 'count') {
                         $tmp_color = '#339900';
                     } elseif ((string) $tmp_arr['type'] == 'set') {
                         $tmp_color = '#778899';
                     } else {
                         // nosql
                         $tmp_color = '#000000';
                     }
                     //end if else
                     //--
                     $log .= '<div class="smartframework_debugbar_inforow" style="font-size:11px; color:' . $tmp_color . ';">';
                     if ((string) $tmp_arr['skip-count'] != 'yes') {
                         $log .= $num . '. ';
                     }
                     //end if else
                     $log .= '<b>' . Smart::escape_html($tmp_arr['data']) . '</b>';
                     if ((string) $tmp_arr['connection'] != '') {
                         $log .= ' @ ' . Smart::escape_html($tmp_arr['connection']);
                     }
                     //end if
                     if ($tmp_arr['time'] > 0) {
                         if ($tmp_arr['time'] <= $db_log['slow-time']) {
                             $log .= '<br><span style="padding:1px;"><b>@Time: ' . Smart::format_number_dec($tmp_arr['time'], 9, '.', '') . ' sec.</b></span>';
                         } else {
                             $log .= '<br><span class="smartframework_debugbar_status_warn" style="padding:1px;" title="Slow-Time: ' . Smart::escape_html($db_log['slow-time']) . '"><b>@Time: ' . Smart::format_number_dec($tmp_arr['time'], 9, '.', '') . ' sec.' . '</b></span>';
                         }
                         //end if else
                     }
                     //end if
                     if ((string) $tmp_arr['query'] != '') {
                         $log .= '<br>' . Smart::escape_html($tmp_arr['query']);
                         if ((string) $tmp_arr['type'] == 'write') {
                             $log .= '<br>' . 'AFFECTED ROWS: #' . $tmp_arr['rows'];
                         }
                         //end if
                         if (Smart::array_size($tmp_arr['params']) > 0) {
                             $tmp_params = array();
                             foreach ($tmp_arr['params'] as $key => $val) {
                                 $tmp_params[] = Smart::escape_html('$' . ($key + 1) . ' => `' . $val . '`');
                             }
                             //end foreach
                             $log .= '<br>' . '@PARAMS:&nbsp;{ ' . implode(', ', $tmp_params) . ' }';
                             $tmp_params = array();
                         }
                         //end if
                     }
                     //end if
                     if (is_array($tmp_arr['command'])) {
                         $tmp_params = array();
                         foreach ($tmp_arr['command'] as $key => $val) {
                             $tmp_params[] = Smart::escape_html($key . ' => `' . self::print_value_by_type($val) . '`');
                         }
                         //end foreach
                         $log .= '<br>' . '@COMMAND-PARAMS:&nbsp;{ ' . implode(', ', $tmp_params) . ' }';
                         $tmp_params = array();
                     } elseif ((string) $tmp_arr['command'] != '') {
                         $log .= '<br>' . Smart::nl_2_br(Smart::escape_html(str_replace(array("\r\n", "\r", "\t"), array("\n", "\n", ' '), $tmp_arr['command'])));
                     }
                     //end if
                     $log .= '</div>';
                     //--
                     break;
                 case 'open-close':
                     //--
                     $tmp_color = '#4285F4';
                     //--
                     $log .= '<div class="smartframework_debugbar_inforow" style="font-size:12px; color:' . $tmp_color . ';">';
                     $log .= '<b>' . Smart::escape_html($tmp_arr['data']) . '</b>';
                     if ((string) $tmp_arr['connection'] != '') {
                         $log .= ' @ ' . Smart::escape_html($tmp_arr['connection']);
                     }
                     //end if
                     $log .= '</div>';
                     //--
                     break;
                 case 'metainfo':
                 default:
                     //--
                     $tmp_color = '#CCCCCC';
                     //--
                     $log .= '<div class="smartframework_debugbar_inforow" style="font-size:12px; color:' . $tmp_color . ';">';
                     $log .= '<b>' . Smart::escape_html($tmp_arr['data']) . '</b>';
                     if ((string) $tmp_arr['connection'] != '') {
                         $log .= ' @ ' . Smart::escape_html($tmp_arr['connection']);
                     }
                     //end if
                     $log .= '</div>';
                     //--
             }
             //end switch
             //--
         }
         //end for
         //--
     } else {
         //--
         $log .= '<div class="smartframework_debugbar_status smartframework_debugbar_status_warn" style="width: 100px; text-align: center;"><font size="2"><b>N/A</b></font></div>';
         //--
     }
     //end if
     //--
     return $log;
     //--
 }
 /**
  * Set the (in-memory) Auth Login Data
  * It can be used just once per execution (session) as it stores the data using constants,
  * and the data cannot be changed after a successful or failed authentication has set.
  *
  * @param 	STRING 	$y_user_id 				:: The user (login) ID used to authenticate the user ; Mandatory ; it can be the UserID from DB or if not using a DB must supply a unique ID to identify the user like username
  * @param 	STRING 	$y_user_alias			:: The user (login) Alias, used to display the logged in user ; Mandatory ; can be the same as the login ID or different (Ex: login ID can be 'myUserName' and this 'myUserName' ; or: login ID can be 5017 and this 'myUserName')
  * @param 	STRING 	$y_user_email 			:: *OPTIONAL* The user Email ; if email is used as login ID this may be redundant !
  * @param 	STRING 	$y_user_fullname 		:: *OPTIONAL* The user Full Name (First Name + Last Name)
  * @param 	ARRAY 	$y_user_privileges_list :: *OPTIONAL* The user Privileges List as array that list all the current user privileges
  * @param 	STRING 	$y_user_quota 			:: *OPTIONAL* The user (storage) Quota
  * @param 	ARRAY 	$y_user_metadata 		:: *OPTIONAL* The user metainfo, associative array key => value
  * @param 	STRING 	$y_realm 				:: *OPTIONAL* The user Authentication Realm(s)
  * @param 	ENUM 	$y_method 				:: *OPTIONAL* The authentication method used: HTTP-BASIC / HTTP-DIGEST / OTHER
  * @param 	STRING 	$y_pass					:: *OPTIONAL* The user login password (will be stored in memory as Blowfish encrypted to avoid exposure)
  *
  * @return 	BOOLEAN							:: TRUE if all data is OK, FALSE if not or try to reauthenticate under the same execution (which is not allowed ; must be just once per execution)
  */
 public static function set_login_data($y_user_id, $y_user_alias, $y_user_email = '', $y_user_fullname = '', $y_user_privileges_list = array('none', 'no-privilege'), $y_user_quota = -1, $y_user_metadata = array(), $y_realm = 'DEFAULT', $y_method = '', $y_pass = '')
 {
     //--
     if (self::$AuthCompleted !== false) {
         // avoid to re-auth
         Smart::log_warning('Re-Authentication is not allowed ...');
         return;
     }
     //end if
     self::$AuthCompleted = true;
     //--
     self::$AuthData = array();
     // reset the auth data
     //--
     $y_user_id = trim((string) $y_user_id);
     // user ID
     $y_user_alias = trim((string) $y_user_alias);
     // username (user alias ; can be the same as userID or different)
     $y_user_email = trim((string) $y_user_email);
     $y_user_fullname = trim((string) $y_user_fullname);
     //--
     if (is_array($y_user_privileges_list)) {
         $y_user_privileges_list = (string) strtolower((string) Smart::array_to_list((array) $y_user_privileges_list));
     } else {
         $y_user_privileges_list = (string) strtolower((string) trim((string) $y_user_privileges_list));
         // in this case can be provided a raw list of privileges (Example: '<none>, <no-privilege>')
     }
     //end if else
     //--
     $y_user_quota = Smart::format_number_int($y_user_quota);
     // can be also negative
     //--
     switch (strtoupper((string) $y_method)) {
         case 'HTTP-BASIC':
             $y_method = 'HTTP-BASIC';
             break;
         case 'HTTP-DIGEST':
             $y_method = 'HTTP-DIGEST';
             break;
         case 'OTHER':
         default:
             $y_method = 'OTHER';
     }
     //end switch
     //--
     $the_key = '#' . Smart::random_number(10000, 99999) . '#';
     $the_pass = '';
     if ((string) $y_pass != '') {
         $the_pass = SmartCipherCrypto::encrypt('hash/sha1', (string) $the_key, (string) $y_pass);
     }
     //end if
     //--
     if ((string) $y_user_id != '') {
         //--
         self::$AuthData['USER_ID'] = (string) $y_user_id;
         self::$AuthData['USER_EMAIL'] = (string) $y_user_email;
         self::$AuthData['USER_ALIAS'] = (string) $y_user_alias;
         self::$AuthData['USER_FULLNAME'] = (string) $y_user_fullname;
         self::$AuthData['USER_PRIVILEGES'] = (string) $y_user_privileges_list;
         self::$AuthData['USER_QUOTA'] = (int) $y_user_quota;
         self::$AuthData['USER_METADATA'] = (array) $y_user_metadata;
         self::$AuthData['USER_LOGIN_REALM'] = (string) $y_realm;
         self::$AuthData['USER_LOGIN_METHOD'] = (string) $y_method;
         self::$AuthData['USER_LOGIN_PASS'] = (string) $the_pass;
         self::$AuthData['KEY'] = (string) $the_key;
         //--
         return true;
         //--
     } else {
         //--
         return false;
         //--
     }
     //end if
     //--
 }
 public static function write_data($db, $query, $params_or_title = '')
 {
     //--
     self::check_connection($db);
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         //--
         $time_start = microtime(true);
         //--
     }
     //end if
     //--
     if (is_array($params_or_title)) {
         $query = self::prepare_param_query($db, $query, $params_or_title);
     }
     //end if
     //--
     $result = @$db->exec($query);
     //--
     if ($result) {
         $affected_rows = @$db->changes();
         // free result is not available for exec, but just for query
         $sqlite_error = '';
     } else {
         $affected_rows = 0;
         $sqlite_error = 'SQLite3-ERR:: ' . @$db->lastErrorMsg();
     }
     //end if
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'sqlite|total-queries', 1, '+');
         //--
         $time_end = (double) (microtime(true) - (double) $time_start);
         SmartFrameworkRegistry::setDebugMsg('db', 'sqlite|total-time', $time_end, '+');
         //--
         if (is_array($params_or_title)) {
             $the_query_title = '';
         } else {
             $the_query_title = (string) $params_or_title;
         }
         //end if else
         //--
         if (strtoupper(substr(trim($query), 0, 5)) == 'BEGIN' or strtoupper(substr(trim($query), 0, 6)) == 'COMMIT' or strtoupper(substr(trim($query), 0, 8)) == 'ROLLBACK') {
             SmartFrameworkRegistry::setDebugMsg('db', 'sqlite|log', ['type' => 'transaction', 'data' => 'TRANSACTION :: ' . $the_query_title, 'query' => $query, 'time' => Smart::format_number_dec($time_end, 9, '.', ''), 'connection' => (string) self::get_connection_id($db)]);
         } else {
             SmartFrameworkRegistry::setDebugMsg('db', 'sqlite|log', ['type' => 'write', 'data' => 'WRITE :: ' . $the_query_title, 'query' => $query, 'rows' => $affected_rows, 'time' => Smart::format_number_dec($time_end, 9, '.', ''), 'connection' => (string) self::get_connection_id($db)]);
         }
         //end if else
         //--
     }
     //end if
     //--
     if (strlen($sqlite_error) > 0) {
         $message = 'errorsqlwriteoperation: ' . $sqlite_error;
         self::error($db, 'WRITE-DATA', $sqlite_error, $query, $params_or_title);
         return array($message, 0);
     } else {
         $message = 'oksqlwriteoperation';
     }
     //end if
     //--
     return array($message, Smart::format_number_int($affected_rows, '+'));
     //--
 }
 /**
  * [PUBLIC] Draw an Image Gallery
  *
  * @param STRING $y_title									:: a title for the gallery
  * @param STRING $y_dir										:: path to scan
  * @param *OPTIONAL[yes/no] $y_process_previews_and_images	:: If = 'yes', will create previews for images and videos (movies) and will create conformed images
  * @param *OPTIONAL[yes/no] $y_remove_originals				:: If = 'yes', will remove original (images) after creating previews [$y_process_previews_and_images must be yes]
  * @param *OPTIONAL[>=0]	$y_display_limit				:: Items limit to display
  */
 public function draw($y_title, $y_dir, $y_process_previews_and_images = 'no', $y_remove_originals = 'no', $y_display_limit = '0')
 {
     //--
     $y_title = (string) $y_title;
     //--
     $y_dir = (string) $y_dir;
     //--
     $y_process_previews_and_images = (string) $y_process_previews_and_images;
     if ((string) $y_process_previews_and_images != 'yes') {
         $y_process_previews_and_images = 'no';
     }
     //end if
     //--
     $y_display_limit = Smart::format_number_int($y_display_limit, '+');
     //--
     //--
     if ((string) $this->use_secure_links == 'yes') {
         if ((string) $this->secure_download_link == '' or (string) $this->secure_download_ctrl_key == '') {
             return '<h1>WARNING: Media Gallery / Secure Links Mode is turned ON but at least one of the: download link or the controller was NOT provided ...</h1>';
         }
         //end if
     }
     //end if
     //--
     //--
     if (!SmartFileSysUtils::check_file_or_dir_name($y_dir)) {
         return '<h1>ERROR: Invalid Folder for Media Gallery ...</h1>';
     }
     //end if
     //--
     $y_dir = SmartFileSysUtils::add_dir_last_slash($y_dir);
     SmartFileSysUtils::raise_error_if_unsafe_path($y_dir);
     //--
     if (!is_dir($y_dir)) {
         return '<h1>WARNING: The Folder for Media Gallery does not exists ...</h1>';
     }
     //end if
     //--
     //--
     $this->gallery_items = 0;
     //--
     //-- constraint of params
     if ((string) $y_process_previews_and_images != 'yes') {
         $y_remove_originals = 'no';
     }
     //end if
     //--
     if (strlen($this->preview_formvar) > 0) {
         // avoid processing if it is displayed in a form
         $y_process_previews_and_images = 'no';
         $y_remove_originals = 'no';
     }
     //end if
     //--
     //-- some inits ...
     $out = '';
     $arr_files = array();
     $processed = 0;
     //--
     //--
     $arr_storage = (array) (new SmartGetFileSystem(true))->get_storage($y_dir, false, false);
     $all_mg_files = (array) $arr_storage['list-files'];
     //--
     //--
     for ($i = 0; $i < Smart::array_size($all_mg_files); $i++) {
         //--
         $file = (string) $all_mg_files[$i];
         $ext = strtolower(SmartFileSysUtils::get_file_extension_from_path($file));
         //--
         if (substr($file, 0, 1) != '.' and strpos($file, '.#') === false and strpos($file, '#.') === false) {
             //--
             if (is_file($y_dir . $file) and ((string) $ext == 'jpeg' or (string) $ext == 'jpg' or (string) $ext == 'gif' or (string) $ext == 'png')) {
                 //--
                 if (SmartFileSysUtils::version_check($file, 'mg-preview')) {
                     //-- it is an image preview file
                     if (!is_file($y_dir . SmartFileSysUtils::version_add($file, 'mg-image'))) {
                         SmartFileSystem::delete($y_dir . $file);
                         // remove preview if orphan
                     }
                     //end if
                     //--
                 } elseif (SmartFileSysUtils::version_check($file, 'mg-image')) {
                     //-- it is an image file
                     if ((string) $y_process_previews_and_images == 'yes') {
                         //--
                         $tmp_file = $y_dir . SmartFileSysUtils::version_add($file, 'mg-preview');
                         //--
                         if (!is_file($tmp_file)) {
                             //--
                             $out .= $this->img_preview_create($y_dir . $file, $tmp_file) . '<br>';
                             $processed += 1;
                             //--
                         }
                         //end if
                         //--
                     }
                     //end if
                     //--
                     $arr_files[] = $file;
                     $this->gallery_items += 1;
                     //--
                 } elseif (SmartFileSysUtils::version_check($file, 'mg-vpreview')) {
                     //-- it is a movie preview file
                     if (stripos($file, '.#tmp-preview#.jpg') === false) {
                         //--
                         $tmp_linkback_file = SmartFileSysUtils::get_noext_file_name_from_path(SmartFileSysUtils::version_remove($file));
                         //--
                         if (!is_file($y_dir . $tmp_linkback_file)) {
                             SmartFileSystem::delete($y_dir . $file);
                             // remove if orphan
                         }
                         //end if
                         //--
                     }
                     //end if
                     //--
                 } else {
                     // unprocessed image
                     //--
                     if ((string) $y_process_previews_and_images == 'yes') {
                         //--
                         $tmp_file = $y_dir . SmartFileSysUtils::version_add($file, 'mg-image');
                         //--
                         if (!is_file($tmp_file)) {
                             //--
                             if ((string) $y_dir . $file != (string) $y_dir . strtolower($file)) {
                                 SmartFileSystem::rename($y_dir . $file, $y_dir . strtolower($file));
                                 // make sure is lowercase, to be ok for back-check since versioned is lowercase
                             }
                             //end if
                             //--
                             $out .= $this->img_conform_create($y_dir . $file, $tmp_file) . '<br>';
                             $processed += 1;
                             //--
                         } else {
                             //--
                             if ((string) $y_remove_originals == 'yes') {
                                 //--
                                 SmartFileSystem::delete($y_dir . $file);
                                 $out .= '<table width="550" bgcolor="#FF3300"><tr><td>removing original image: \'' . Smart::escape_html($file) . '\'</td></tr></table><br>';
                                 $processed += 1;
                                 //--
                             }
                             //end if
                             //--
                         }
                         //end if else
                         //--
                     }
                     //end if
                     //--
                 }
                 //end if else
                 //--
             } elseif (is_file($y_dir . $file) and ((string) $ext == 'webm' or (string) $ext == 'ogv' or (string) $ext == 'mp4' or (string) $ext == 'mov' or (string) $ext == 'flv')) {
                 // WEBM, OGV, MP4, MOV, FLV
                 //-- process preview FLV / MOV ...
                 if ((string) $y_process_previews_and_images == 'yes') {
                     //--
                     $tmp_file = $y_dir . SmartFileSysUtils::version_add($file, 'mg-vpreview') . '.jpg';
                     //--
                     if (!is_file($tmp_file)) {
                         //--
                         if ((string) $y_dir . $file != (string) $y_dir . strtolower($file)) {
                             SmartFileSystem::rename($y_dir . $file, $y_dir . strtolower($file));
                             // make sure is lowercase, to be ok for back-check since versioned is lowercase
                         }
                         //end if
                         //--
                         $out .= $this->mov_preview_create($y_dir . strtolower($file), $tmp_file) . '<br>';
                         $processed += 1;
                         //--
                     }
                     //end if
                     //--
                 }
                 //end if
                 //--
                 $arr_files[] = $file;
                 $this->gallery_items += 1;
                 //--
             }
             //end if else
             //--
         }
         //end if
         //--
     }
     //end for
     //--
     //--
     $out .= '<!-- START MEDIA GALLERY -->' . "\n";
     //--
     if ((string) $this->use_styles == 'yes') {
         $out .= '<div id="mediagallery_box">' . "\n";
     }
     //end if
     //--
     //--
     $out_arr = array();
     //--
     if ($processed <= 0) {
         //--
         $arr_files = Smart::array_sort($arr_files, 'natsort');
         //--
         $max_loops = Smart::array_size($arr_files);
         if ($y_display_limit > 0) {
             if ($y_display_limit < $max_loops) {
                 $max_loops = $y_display_limit;
             }
             //end if
         }
         //end if
         //--
         for ($i = 0; $i < $max_loops; $i++) {
             //--
             $tmp_the_ext = strtolower(SmartFileSysUtils::get_file_extension_from_path($arr_files[$i]));
             // [OK]
             //--
             if ((string) $tmp_the_ext == 'webm' or (string) $tmp_the_ext == 'ogv' or (string) $tmp_the_ext == 'mp4' or (string) $tmp_the_ext == 'mov' or (string) $tmp_the_ext == 'flv') {
                 $out_arr[] = $this->mov_draw_box($y_dir, $arr_files[$i], $tmp_the_ext);
             } else {
                 $out_arr[] = $this->img_draw_box($y_dir, $arr_files[$i]);
             }
             //end if
             //--
         }
         //end for
         //--
         $out .= '<div title="' . Smart::escape_html($this->gallery_show_counter) . '">' . "\n";
         //--
         if ((string) $y_title != '') {
             $out .= '<div id="mediagallery_title">' . Smart::escape_html($y_title) . '</div><br>';
         }
         //end if
         $out .= '<div id="mediagallery_row">';
         for ($i = 0; $i < Smart::array_size($out_arr); $i++) {
             $out .= '<div id="mediagallery_cell">';
             $out .= $out_arr[$i];
             $out .= '</div>' . "\n";
         }
         //end for
         $out .= '</div>';
         //--
         $out .= '</div>' . "\n";
         //--
     }
     //end if
     //--
     $out_arr = array();
     //--
     //--
     if ((string) $this->use_styles == 'yes') {
         $out .= '</div>' . "\n";
     }
     //end if
     //--
     $out .= '<!-- END MEDIA GALLERY -->' . "\n";
     //--
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE != 'yes') {
         if ($processed > 0) {
             $out = '<img src="' . $this->pict_reloading . '" alt="[Reloading Page ...]" title="[Reloading Page ...]"><script type="text/javascript">setTimeout(function(){ self.location = self.location; }, 2000);</script>' . '<br><hr><br>' . $out;
             define('SMART_FRAMEWORK__MEDIA_GALLERY_IS_PROCESSING', $processed);
             // notice that the media galery is processing
         }
         //end if
     }
     //end if
     //--
     //--
     return $out;
     //--
 }
 /**
  * Object Constructor
  *
  * @access 		private
  * @internal
  *
  */
 public function __construct($mode = 'json', $host = '', $port = '', $ssl = '', $db = '', $user = '', $password = '', $timeout = 5, $y_debug_exch_slowtime = 0.33, $y_description = 'DEFAULT')
 {
     //--
     global $configs;
     //--
     if ((string) $host == '' and (string) $port == '' and (string) $db == '') {
         $mode = (string) $configs['solr']['mode'];
         $host = (string) $configs['solr']['server-host'];
         $port = (int) $configs['solr']['server-port'];
         $ssl = (bool) $configs['solr']['server-ssl'];
         $db = (string) $configs['solr']['db'];
         $user = (string) $configs['solr']['username'];
         $password = (string) base64_decode((string) $configs['solr']['password']);
         $timeout = (int) $configs['solr']['timeout'];
         $y_debug_exch_slowtime = 0 + $configs['solr']['slowtime'];
     }
     //end if
     //--
     if ((string) $mode != 'xml') {
         // need to be before raising any errors as it is used in error display
         $mode = 'json';
     }
     //end if else
     $this->mode = (string) $mode;
     //--
     if (version_compare(phpversion('solr'), '2.0') < 0) {
         $this->error('PHP Solr Extension', 'This version of SOLR Client Library needs the Solr PHP Extension version 2.0 or later', 'CHECK PHP Solr Version');
         return;
     }
     //end if
     //--
     if ((string) $host == '' or (string) $port == '' or (string) $db == '' or (string) $timeout == '') {
         $this->error('Solr Configuration Init', 'Some Required Parameters are Empty', 'CHECK Connection Params');
         return;
     }
     //end if
     //--
     $this->host = (string) $host;
     $this->port = (int) $port;
     $this->ssl = (bool) $ssl;
     //--
     $this->db = (string) $db;
     //--
     $this->user = (string) $user;
     $this->password = (string) $password;
     //--
     $this->timeout = Smart::format_number_int($timeout, '+');
     if ($this->timeout < 1) {
         $this->timeout = 1;
     }
     //end if
     if ($this->timeout > 30) {
         $this->timeout = 30;
     }
     //end if
     //--
     $this->description = (string) $y_description;
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         //--
         if ((double) $y_debug_exch_slowtime > 0) {
             $this->slow_time = (double) $y_debug_exch_slowtime;
         }
         //end if
         if ($this->slow_time < 1.0E-7) {
             $this->slow_time = 1.0E-7;
         } elseif ($this->slow_time > 0.9999999000000001) {
             $this->slow_time = 0.9999999000000001;
         }
         //end if
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'solr|slow-time', number_format($this->slow_time, 7, '.', ''), '=');
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'solr|log', ['type' => 'metainfo', 'data' => 'Solr App Connector Version: ' . SMART_FRAMEWORK_MODULES_VERSION]);
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'solr|log', ['type' => 'metainfo', 'data' => 'Connection Timeout: ' . $this->timeout . ' seconds']);
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'solr|log', ['type' => 'metainfo', 'data' => 'Fast Query Reference Time < ' . $this->slow_time . ' seconds']);
         //--
     }
     //end if
     //--
 }
 /**
  * Set a Key into the persistent Cache
  *
  * @param STRING 	$y_realm		The Cache Realm
  * @param STRING 	$y_key			The Cache Key
  * @param MIXED 	$y_value		The value to be stored
  * @param INTEGER+ 	$y_expiration	Key Expiration in seconds (zero if key does not expire)
  *
  * @return BOOLEAN	Returns True if the key was set or false if not
  */
 public static function setKey($y_realm, $y_key, $y_value, $y_expiration = 0)
 {
     //--
     if (!self::isActive()) {
         return false;
     }
     //end if
     //--
     if (!self::validateRealm((string) $y_realm)) {
         Smart::log_warning('Persistent Cache / Invalid Realm: ' . $y_realm);
         return false;
     }
     //end if
     if (!self::validateKey((string) $y_key)) {
         Smart::log_warning('Persistent Cache / Invalid Key: ' . $y_key);
         return false;
     }
     //end if
     //--
     self::initCacheManager();
     //--
     $y_value = (string) SmartUnicode::fix_charset((string) $y_value);
     // fix
     $y_expiration = Smart::format_number_int($y_expiration, '+');
     //--
     $resexp = 1;
     if ((string) $y_realm == '') {
         $result = self::$redis->set((string) $y_key, (string) $y_value);
         if ($y_expiration > 0) {
             $resexp = self::$redis->expire((string) $y_key, (int) $y_expiration);
         }
         //end if
     } else {
         $result = self::$redis->set((string) $y_realm . ':' . $y_key, (string) $y_value);
         if ($y_expiration > 0) {
             $resexp = self::$redis->expire((string) $y_realm . ':' . $y_key, (int) $y_expiration);
         }
         //end if
     }
     //end if else
     //--
     if (strtoupper(trim((string) $result)) == 'OK' and $resexp == 1) {
         return true;
     } else {
         return false;
     }
     //end if else
     //--
 }
 public static function main_screen($tab, $frm, $testformdata)
 {
     //--
     global $configs;
     //--
     //--
     if (!defined('SMART_FRAMEWORK_TESTUNIT_BASE_URL')) {
         http_response_code(500);
         die(SmartComponents::http_message_500_internalerror('ERROR: TEST UNIT BASE URL has not been defined ...'));
     }
     //end if
     //--
     //--
     if (Smart::array_size($testformdata) > 0) {
         // because is modal we have to close it in order to refresh the parent
         return '<table><tr><td><h1>Form Sent (Test) !</h1><hr><pre>' . Smart::escape_html(print_r($testformdata, 1)) . '</pre></td></tr></table><script>SmartJS_BrowserUtils.RefreshParent();</script><br><br><input id="myCloseButton" type="button" value="[Close Me]" onClick="SmartJS_BrowserUtils.CloseModalPopUp(); return false;"><br><br><b>This page will auto-close in 9 seconds [Counting: <span id="mycounter">9</span>]</b><script>jQuery("#myCloseButton").button(); SmartJS_BrowserUtils.CountDown(9, \'mycounter\', \'SmartJS_BrowserUtils.CloseDelayedModalPopUp(500);\');</script><br><br><b><i>After closing this window, parent will refresh ...</i></b>';
     }
     //end if
     //--
     //-- normal form with modal/popup
     $basic_form_start = '<form id="form_for_test" action="' . SMART_FRAMEWORK_TESTUNIT_BASE_URL . 'testunit.main&tab=1' . '&' . SMART_FRAMEWORK_URL_PARAM_MODALPOPUP . '=' . SMART_FRAMEWORK_URL_VALUE_ENABLED . '" method="post" target="_blank"><input type="hidden" name="testformdata[test]" value="Testing ..."><input type="hidden" name="testformdata[another-test]" value="Testing more ...">';
     $basic_form_end = '</form>';
     //--
     $basic_form_send_modal = '<input class="ux-button ux-button-primary" style="min-width:325px;" type="submit" value="Submit Form (with Confirmation / Modal)" OnClick="' . SmartComponents::js_draw_html_confirm_form_submit('<div align="left"><h3><b>Are you sure you want to submit this form [MODAL] ?</b></h3></div>', 'my_form') . '">';
     $basic_form_send_popup = '<input class="ux-button ux-button-secondary" style="min-width:325px;" type="submit" value="Submit Form (with Confirmation / PopUp)" OnClick="' . SmartComponents::js_draw_html_confirm_form_submit('<div align="left"><h3><b>Are you sure you want to submit this form [POPUP] ?</b></h3></div>', 'my_form', '780', '420', '1') . '">';
     //--
     //-- AJAX POST FORM
     $btnop = '<button class="ux-button ux-button-large ux-button-highlight" onClick="' . SmartComponents::post_form_by_ajax('test_form_ajax', SMART_FRAMEWORK_TESTUNIT_BASE_URL . 'testunit.post-form-by-ajax&tab=2', '<h2>Are you sure you want to submit this form by Ajax !?</h2>') . ' return false;">Submit this Test Form by AJAX &nbsp; <span class="fa fa-send"></span></button>';
     //-- END
     //-- lists with one element
     $one_single_select = SmartComponents::html_single_select_list('test-unit-s-list-one', '', 'form', array('one' => 'One'), 'frm[one_single]', '150', '', 'no', 'no', '#JS-UI#');
     // returns HTML Code
     $one_single_with_blank_select = SmartComponents::html_multi_select_list('test-unit-lst-m-1', '', 'form', array('one' => 'One'), 'frm[one_multi][]', 'list', 'no', '200', '', '#JS-UI-FILTER#');
     // returns HTML Code
     //--
     $test_normal_list_s = SmartComponents::html_single_select_list('test_normal_s', '', 'form', [1 => 'Val 1', 2 => 'Val 2', 3 => 'Val 3']);
     $test_normal_list_m = SmartComponents::html_multi_select_list('test_normal_m', '', 'form', [1 => 'Val 1', 2 => 'Val 2', 3 => 'Val 3'], '', 'list', 'no', '200/75', '', 'height:65px;');
     //--
     //-- misc purpose data array
     $array_of_values = array();
     $array_of_values[] = 'a&"/><i>Italic</i></body>';
     $array_of_values[] = 'a&"/><i>Italic</i></body>';
     $array_of_values[] = '#OPTGROUP#';
     $array_of_values[] = 'Labels';
     for ($i = 1; $i <= 500; $i++) {
         $array_of_values[] = 'id' . $i;
         $array_of_values[] = 'Label ' . $i;
     }
     //end for
     //-- single-select
     $selected_value = 'id2';
     $elem_single_select = SmartComponents::html_single_select_list('test-unit-s-list-two', $selected_value, 'form', $array_of_values, 'frm[list_single]', '150', 'onChange="alert(\'' . Smart::escape_js('Getting value from the "SingleList": ') . '\' + $(\'#test-unit-s-list-two\').val());"', 'no', 'yes', '#JS-UI-FILTER#');
     // returns HTML Code
     //--
     // draw a multi-select (classic)
     $selected_values = '<id1>,<id3>';
     $elem_multi_select = SmartComponents::html_multi_select_list('test-unit-m-list-2', $selected_values, 'form', $array_of_values, 'frm[list_multi_one][]', 'list', 'no', '250', 'onBlur="alert(\'' . Smart::escape_js('Getting value from the:' . "\n" . ' "MultiList": ') . '\' + $(\'#test-unit-m-list-2\').val());"', '#JS-UI-FILTER#');
     // returns HTML Code
     //--
     // multi-select (checkboxes)
     $array_of_values = array('id1' => 'Label 1', 'id2' => 'Label 2', 'id3' => 'Label 3');
     $selected_values = array('id2', 'id3');
     $elem_multi_boxes = SmartComponents::html_multi_select_list('test-unit-m-list-3', $selected_values, 'form', $array_of_values, 'frm[list_multi_two][]', 'checkboxes');
     // returns HTML Code
     //--
     //--
     if (SMART_FRAMEWORK_ADMIN_AREA === true) {
         $info_adm = '[ Admin Area ]';
     } else {
         $info_adm = '[ Index ]';
     }
     //end if else
     //--
     //--
     $demo_mod_js_components = '<h1>JS Components are not Installed ...</h1>';
     if (SmartAppInfo::TestIfModuleExists('mod-js-components')) {
         $demo_mod_js_components = SmartFileSystem::staticread('modules/mod-js-components/views/testunit/tab-js-components.inc.htm');
     }
     //end if
     //--
     //--
     return SmartMarkersTemplating::render_file_template('lib/core/templates/testunit/test-unit.htm', array('@SUB-TEMPLATES@' => ['test-unit-tab-tests.htm' => 'lib/core/templates/testunit/', 'test-unit-tab-interractions.htm' => 'lib/core/templates/testunit', 'test-unit-tab-ui.htm' => '@', '%test-unit-tab-misc%' => '@/test-unit-tab-misc.htm'], 'TESTUNIT_BASE_URL' => SMART_FRAMEWORK_TESTUNIT_BASE_URL, 'NO-CACHE-TIME' => time(), 'CURRENT-DATE-TIME' => date('Y-m-d H:i:s O'), 'TEST-JS_SCRIPTS.Init-Tabs' => SmartComponents::js_ajx_tabs_init('tabs_draw', Smart::format_number_int($tab, '+')), 'Test-Buttons.AJAX-POST' => $btnop, 'TEST-VAR' => '<div style="background-color: #ECECEC; padding: 10px;"><b>Smart.Framework</b> :: PHP/Javascript web framework :: ' . $info_adm . ' // Test Suite</div>', 'TEST-ELEMENTS.DIALOG' => '<a class="ux-button" style="min-width:325px;" href="#" onClick="' . SmartComponents::js_draw_html_confirm_dialog('<h1>Do you like this framework ?</h1>', 'alert(\'Well ... then \\\' " <tag> !\');') . ' return false;">Test JS-UI Dialog</a>', 'TEST-ELEMENTS.ALERT' => '<a class="ux-button" style="min-width:325px;" href="#" onClick="' . SmartComponents::js_draw_html_alert('<h2>You can press now OK !</h2>', 'alert(\'Good ... \\\' " <tag> !\');') . ' return false;">Test JS-UI Alert</a>', 'TEST-ELEMENTS.SEND-CONFIRM-MODAL' => $basic_form_start . $basic_form_send_modal . $basic_form_end, 'TEST-ELEMENTS.SEND-CONFIRM-POPUP' => $basic_form_start . $basic_form_send_popup . $basic_form_end, 'TEST-ELEMENTS-WND-INTERRACTIONS-MODAL' => self::bttn_open_modal(true, 'test_interractions_modal_start'), 'TEST-ELEMENTS-WND-INTERRACTIONS-POPUP' => self::bttn_open_popup(true, 'test_interractions_popup_start'), 'TEST-ELEMENTS.SINGLE-SELECT' => 'SingleSelect DropDown List without Blank: ' . $one_single_select, 'TEST-ELEMENTS.SINGLE-BLANK-SELECT' => 'SingleSelect DropDown List (from Multi): ' . $one_single_with_blank_select, 'TEST-ELEMENTS.SINGLE-SEARCH-SELECT' => 'SingleSelect DropDown List with Search: ' . $elem_single_select, 'TEST-ELEMENTS.MULTI-SELECT' => 'MultiSelect DropDown List: ' . $elem_multi_select, 'TEST-ELEMENTS.MULTIBOX-SELECT' => 'MultiSelect CheckBoxes:<br>' . $elem_multi_boxes, 'TEST-ELEMENTS.NORMAL-LIST-S' => $test_normal_list_s, 'TEST-ELEMENTS.NORMAL-LIST-M' => $test_normal_list_m, 'TEST-ELEMENTS.CALENDAR' => 'Calendar Selector: ' . SmartComponents::js_draw_date_field('frm_calendar_id', 'frm[date]', Smart::escape_html($frm['date']), 'Select Date', "'0d'", "'1y'", '', 'alert(\'You selected the date: \' + date);'), 'TEST-ELEMENTS.TIMEPICKER' => 'TimePicker Selector: ' . SmartComponents::js_draw_time_field('frm_timepicker_id', 'frm[time]', Smart::escape_html($frm['time']), 'Select Time', '9', '19', '0', '55', '5', '3', '', 'alert(\'You selected the time: \' + time);'), 'TEST-ELEMENTS.AUTOCOMPLETE-SINGLE' => 'AutoComplete: ' . '<input id="auto-complete-fld" type="text" name="frm[autocomplete]" style="width:75px;">' . SmartComponents::js_draw_ui_autocomplete_single('auto-complete-fld', SMART_FRAMEWORK_TESTUNIT_BASE_URL . 'testunit.autocomplete', 'src', 1, 'alert(\'You selected: \' + value);') . ' &nbsp; ' . '<input id="auto-complete-mfld" type="text" name="frm[mautocomplete]" style="width:125px;">' . SmartComponents::js_draw_ui_autocomplete_multi('auto-complete-mfld', SMART_FRAMEWORK_TESTUNIT_BASE_URL . 'testunit.autocomplete', 'src', 1, 'alert(\'You selected: \' + value);'), 'TEST-elements.Captcha' => SmartCaptchaFormCheck::captcha_form(SMART_FRAMEWORK_TESTUNIT_BASE_URL . 'testunit.captcha', self::captcha_form_name()), 'test-elements.limited-area' => 'Limited TextArea: ' . SmartComponents::js_draw_limited_text_area('', 'frm[text_area_1]', '', 300, '400px', '100px'), 'POWERED-INFO' => SmartComponents::draw_powered_info('no'), 'STR-NUM' => '1abc', 'NUM-NUM' => '0.123456789', 'MARKER' => '1234567890.abcdefghijklmniopqrstuvwxyz"', 'IFTEST' => Smart::random_number(1, 2), 'IF2TEST' => Smart::random_number(0, 9), 'LOOPTEST-VAR1' => [['d1' => 'Column 1.x (HTML Escape)', 'd2' => 'Column 2.x (JS Escape)', 'd3' => 'Column 3.x (URL Escape)']], 'LOOPTEST-VAR2' => [['c1' => '<Column 1.1>', 'c2' => 'Column 1.2' . "\n", 'c3' => 'Column 1.3' . "\t"], ['c1' => '<Column 2.1>', 'c2' => 'Column 2.2' . "\n", 'c3' => 'Column 2.3' . "\t"], ['c1' => '<Column 3.1>', 'c2' => 'Column 3.2' . "\n", 'c3' => 'Column 3.3' . "\t"], ['c1' => Smart::random_number(0, 1), 'c2' => 'a', 'c3' => 'A']], 'MOD-JS-COMPONENTS' => $demo_mod_js_components), 'yes');
     //--
 }
 /**
  * Class constructor
  *
  * @param 	STRING 	$col 				:: MongoDB Collection
  * @param 	ARRAY 	$y_configs_arr 		:: The Array of Configuration parameters - the ARRAY STRUCTURE should be identical with the default config.php: $configs['mongodb'].
  *
  */
 public function __construct($col, $y_configs_arr = array())
 {
     //--
     global $configs;
     //--
     if (version_compare(phpversion('mongodb'), '1.0.0') < 0 and version_compare(phpversion('mongo'), '1.4.5') < 0) {
         $this->error('[INIT]', 'PHP MongoDB/Mongo Extension', 'CHECK PHP MongoDB/Mongo Version', 'This version of MongoDB/Mongo Client Library needs either MongoDB PHP Extension v.1.0.0 or later or Mongo PHP Extension v.1.4.5 or later');
         return;
     }
     //end if
     //--
     $this->collection = trim((string) $col);
     //--
     $y_configs_arr = (array) $y_configs_arr;
     //--
     if (Smart::array_size($y_configs_arr) > 0) {
         // use from constructor
         //--
         $db = (string) $y_configs_arr['db'];
         $host = (string) $y_configs_arr['server-host'];
         $port = (string) $y_configs_arr['server-port'];
         $timeout = (string) $y_configs_arr['timeout'];
         $username = (string) $y_configs_arr['username'];
         $password = (string) $y_configs_arr['password'];
         //--
     } else {
         // try to use the configuration default values
         //--
         $db = (string) $configs['mongodb']['db'];
         $host = (string) $configs['mongodb']['server-host'];
         $port = (string) $configs['mongodb']['server-port'];
         $timeout = (string) $configs['mongodb']['timeout'];
         $username = (string) $configs['mongodb']['username'];
         $password = (string) $configs['mongodb']['password'];
         //--
     }
     //end if
     //--
     if ((string) $password != '') {
         $password = (string) base64_decode((string) $password);
     }
     //end if
     //--
     if ((string) $host == '' or (string) $port == '' or (string) $db == '' or (string) $timeout == '') {
         $this->error('[CHECK-CONFIGS]', 'MongoDB Configuration Init', 'CHECK Connection Params: ' . $host . ':' . $port . '@' . $db, 'Some Required Parameters are Empty');
         return;
     }
     //end if
     //--
     $this->server = (string) $host . ':' . $port;
     //--
     $this->db = (string) $db;
     //--
     $this->timeout = Smart::format_number_int($timeout, '+');
     if ($this->timeout < 1) {
         $this->timeout = 1;
     }
     //end if
     if ($this->timeout > 60) {
         $this->timeout = 60;
     }
     //end if
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'mongodb|log', ['type' => 'metainfo', 'data' => 'MongoDB App Connector Version: ' . SMART_FRAMEWORK_MODULES_VERSION]);
         //--
         if ((double) $configs['mongodb']['slowtime'] > 0) {
             $this->slow_time = (double) $configs['mongodb']['slowtime'];
         }
         //end if
         if ($this->slow_time < 1.0E-7) {
             $this->slow_time = 1.0E-7;
         } elseif ($this->slow_time > 0.9999999000000001) {
             $this->slow_time = 0.9999999000000001;
         }
         //end if
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'mongodb|slow-time', number_format($this->slow_time, 7, '.', ''), '=');
         SmartFrameworkRegistry::setDebugMsg('db', 'mongodb|log', ['type' => 'metainfo', 'data' => 'Fast Query Reference Time < ' . number_format($this->slow_time, 7, '.', '') . ' seconds']);
         //--
     }
     //end if
     //--
     $options = array('connect' => false, 'connectTimeoutMS' => $this->timeout * 1000, 'socketTimeoutMS' => SMART_FRAMEWORK_NETSOCKET_TIMEOUT * 1000, 'w' => 1, 'wTimeoutMS' => 0, 'db' => $this->db);
     if ((string) $username != '') {
         $options['username'] = (string) $username;
         if ((string) $password != '') {
             $options['password'] = (string) $password;
             $options['authMechanism'] = 'MONGODB-CR';
         }
         //end if
     }
     //end if
     //--
     /*
     	if(class_exists('\\MongoDB\\Driver\\Manager')) {
     		$this->mongodbclient = new \MongoDB\Driver\Manager(
     			(string) 'mongodb://'.$this->server,
     			(array) $options
     		);
     	} elseif(class_exists('MongoClient')) {
     */
     if (class_exists('MongoClient')) {
         $this->mongoclient = new MongoClient((string) $this->server, (array) $options);
     } else {
         $this->error((string) $the_conns[0]['hash'], 'MongoDB Driver', 'No Compatible MongoDB Driver found', '');
     }
     //end if else
     //--
 }
 /**
  * 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
     //--
 }
 /**
  * Load/Save a cache file from Memory or from a URL
  *
  * @param STRING 	$y_cache_file_extension		:: File Extension (example: '.ext')
  * @param STRING 	$y_cache_prefix				:: prefix dir (at least 3 chars) ended by slash (Example: 'prefix/')
  * @param STRING 	$y_load_url					:: URL to Load (Ex: http(s)://some/test.txt ; memory://some.unique.key)
  * @param STRING	$y_content					:: just for memory:// ; contents of the file to be saved into cache - [set] mode ; if this is empty will just get
  * @param INT 		$y_cache_expire				:: 0=never ; (>0)=seconds
  * @param ENUM 		$y_encrypted				:: yes/no to encrypt the file content
  * @return MIXED								:: cached contents
  */
 public static function load_cached_content($y_cache_file_extension, $y_cache_prefix, $y_load_url, $y_content = '', $y_cache_expire = 0, $y_encrypted = 'no')
 {
     // v.150209
     //--
     $y_load_url = (string) $y_load_url;
     //--
     if ((string) $y_load_url == '') {
         Smart::log_warning('Utils // Load From Cache ... Empty URL ...');
         return '';
     }
     //end if
     //--
     //--
     $y_cache_file_extension = Smart::safe_validname($y_cache_file_extension);
     //--
     $y_cache_expire = Smart::format_number_int($y_cache_expire, '+');
     //--
     $y_cache_prefix = (string) $y_cache_prefix;
     //--
     if (strlen($y_cache_prefix) >= 3 and strlen($y_cache_prefix) <= 64) {
         //--
         $y_cache_prefix = SmartFileSysUtils::add_dir_last_slash($y_cache_prefix);
         // fix trailing slash
         //--
     } else {
         //--
         $y_cache_prefix = 'default/';
         //--
     }
     //end if
     //--
     //--
     $unique_id = (string) SmartHashCrypto::sha1('@@::SmartFramework::Content::Cache@@' . $y_load_url);
     //--
     $dir = 'tmp/cache/' . $y_cache_prefix . SmartFileSysUtils::prefixed_sha1_path($unique_id);
     SmartFileSysUtils::raise_error_if_unsafe_path($dir);
     //--
     $file = (string) $dir . $unique_id . $y_cache_file_extension;
     SmartFileSysUtils::raise_error_if_unsafe_path($file);
     //--
     //--
     if (!is_dir($dir)) {
         SmartFileSystem::dir_recursive_create($dir);
     }
     // end if
     //--
     $protect_file = $dir . 'index.html';
     if (!is_file($protect_file)) {
         SmartFileSystem::write($protect_file, '');
     }
     //end if
     //--
     //-- will go through this only if cache expired or no cache
     if (!is_file($file) or is_file($file) and $y_cache_expire > 0 and @filemtime($file) + $y_cache_expire < time()) {
         //-- read
         if (substr($y_load_url, 0, 9) == 'memory://' and (string) $y_content != '') {
             //-- set the content from memory
             $tmp_content = (string) $y_content;
             $tmp_result = '1';
             $tmp_code = '200';
             //--
         } elseif (substr($y_load_url, 0, 9) != 'memory://') {
             //--
             $arr = self::load_url_or_file($y_load_url);
             // [OK]
             $tmp_result = $arr['result'];
             $tmp_code = $arr['code'];
             $tmp_content = $arr['content'];
             $arr = array();
             //--
         }
         //end if else
         //-- if required, apply encryption
         if ((string) $y_encrypted == 'yes') {
             //--
             $tmp_content = self::crypto_blowfish_encrypt($tmp_content);
             //--
         }
         //end if
         //-- write to cache
         if ((string) $tmp_result == '1' and (string) $tmp_code == '200') {
             //--
             SmartFileSystem::write($file, $tmp_content);
             // save file to cache (safe write is controlled via locks)
             //--
         }
         //end if
         //--
         $tmp_content = '';
         //--
     }
     //end if
     //--
     //-- get from cache
     $out = SmartFileSystem::read($file);
     //--
     if ((string) $y_encrypted == 'yes') {
         $out = self::crypto_blowfish_decrypt($out);
     }
     //end if
     //--
     //--
     return $out;
     //--
 }
 /**
  * Object Constructor
  *
  * @access 		private
  * @internal
  *
  */
 public function __construct($host, $port, $db, $password = '', $timeout = 5, $y_debug_exch_slowtime = 0.0005, $y_description = 'DEFAULT', $y_ignore_connection_fail = true)
 {
     //--
     if ((string) $host == '' or (string) $port == '' or (string) $db == '' or (string) $timeout == '') {
         $this->error(true, 'Redis Configuration Init', 'Some Required Parameters are Empty', 'CFG:host:port@db#timeout');
         // fatal error
         return;
     }
     //end if
     //--
     $this->server = $host . ':' . $port;
     //--
     $this->db = Smart::format_number_int($db, '+');
     if ($this->db < 0) {
         $this->db = 0;
     }
     //end if
     if ($this->db > 15) {
         $this->db = 15;
     }
     //end if
     //--
     $this->timeout = Smart::format_number_int($timeout, '+');
     if ($this->timeout < 1) {
         $this->timeout = 1;
     }
     //end if
     if ($this->timeout > 30) {
         $this->timeout = 30;
     }
     //end if
     //--
     if ((string) $password != '') {
         $this->password = (string) base64_decode((string) $password);
     } else {
         $this->password = '';
     }
     //end if else
     //--
     $this->description = (string) $y_description;
     //--
     $y_ignore_connection_fail = (bool) $y_ignore_connection_fail;
     if ($y_ignore_connection_fail === true) {
         $this->raise_fatal_err_on_connection_fail = false;
         $txt_conn = 'IGNORED BUT LOGGED AS WARNINGS';
     } else {
         $this->raise_fatal_err_on_connection_fail = true;
         $txt_conn = 'FATAL ERRORS';
     }
     //end if else
     //--
     $this->err = false;
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         //--
         if ((double) $y_debug_exch_slowtime > 0) {
             $this->slow_time = (double) $y_debug_exch_slowtime;
         }
         //end if
         if ($this->slow_time < 1.0E-7) {
             $this->slow_time = 1.0E-7;
         } elseif ($this->slow_time > 0.9999999000000001) {
             $this->slow_time = 0.9999999000000001;
         }
         //end if
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'redis|slow-time', number_format($this->slow_time, 7, '.', ''), '=');
         SmartFrameworkRegistry::setDebugMsg('db', 'redis|log', ['type' => 'metainfo', 'data' => 'Redis App Connector Version: ' . SMART_FRAMEWORK_VERSION . ' // Connection Errors are: ' . $txt_conn]);
         //--
     }
     //end if
     //--
 }
 private function folder_iterator($recurring, $dir_name, $include_dot_files, $search_pattern = '', $search_prevent_file = '', $search_prevent_override = '')
 {
     //--
     $recurring = (bool) $recurring;
     $dir_name = (string) $dir_name;
     $include_dot_files = (bool) $include_dot_files;
     $search_pattern = (string) $search_pattern;
     $search_prevent_file = (string) $search_prevent_file;
     $search_prevent_override = (string) $search_prevent_override;
     //--
     if ((string) $dir_name == '') {
         Smart::log_warning('LibFileSys // ReadsFolderRecurring // Dir Name is Empty !');
         return;
         // this function does not return anything, but just stop here in this case
     }
     //end if
     //-- fix invalid path (must end with /)
     $dir_name = SmartFileSysUtils::add_dir_last_slash($dir_name);
     //-- protection
     SmartFileSysUtils::raise_error_if_unsafe_path($dir_name);
     //--
     @clearstatcache();
     //--
     $this->pattern_search_str = $search_pattern;
     $this->search_prevent_file = $search_prevent_file;
     $this->search_prevent_override = $search_prevent_override;
     //--
     if (SmartFileSystem::file_or_link_exists($dir_name) and !is_file($dir_name)) {
         // can be dir or link
         //list
         //--
         if ($handle = opendir($dir_name)) {
             //---------------------------------------
             while (false !== ($file = readdir($handle))) {
                 //--
                 if ((string) $file != '.' and (string) $file != '..') {
                     //--
                     if ($include_dot_files or !$include_dot_files and substr($file, 0, 1) != '.') {
                         //--
                         SmartFileSysUtils::raise_error_if_unsafe_path($dir_name . $file);
                         //-- params to see if counted or added to pattern matches
                         $tmp_allow_addition = 1;
                         $tmp_add_pattern = 0;
                         //-- this is for #private folders, will prevent searching in folders containing for example this file: .private-folder but can be overriden by the $search_prevent_override option exluding a particular path like folder/private/user1
                         if (strlen($search_prevent_file) > 0 and is_file($dir_name . $search_prevent_file)) {
                             if (strlen($search_prevent_override) <= 0 or strlen($search_prevent_override) > 0 and !is_file($dir_name . $search_prevent_override)) {
                                 $tmp_allow_addition = 0;
                             }
                             //end if
                         }
                         //end if
                         //-- this is a search pattern (search pattern does not apply to folders !!) ; if no empty will populate the pattern matches array with all files and folders matching ; to include all, use * or a particular search for the rest like myfile1
                         if ((string) $search_pattern == '' or is_dir($dir_name . $file)) {
                             if ($tmp_allow_addition) {
                                 if ($this->list_files_and_dirs) {
                                     $tmp_add_pattern = 1;
                                 }
                                 //end if
                             }
                             //end if
                         } else {
                             if ($this->limit_search_files <= 0 or Smart::array_size($this->pattern_file_matches) < $this->limit_search_files) {
                                 if ((string) $search_pattern == '*' or (string) $search_pattern == '[image]' and (substr($file, -4, 4) == '.png' or substr($file, -4, 4) == '.gif' or substr($file, -4, 4) == '.jpg' or substr($file, -5, 5) == '.jpeg') or (string) $search_pattern != '*' and (string) $search_pattern != '[image]' and stripos($file, $search_pattern) !== false) {
                                     if ($tmp_allow_addition) {
                                         if ($this->list_files_and_dirs) {
                                             $tmp_add_pattern = 1;
                                         }
                                         //end if
                                     }
                                     //end if
                                 } else {
                                     $tmp_allow_addition = 0;
                                 }
                                 //end if else
                             }
                             //end if
                         }
                         //end if
                         //--
                         if ($this->limit_search_files > 0) {
                             // the dir should not be taken in count here
                             if ($this->num_files + $this->num_links >= $this->limit_search_files) {
                                 break;
                             }
                             //end if
                         }
                         //end if
                         //--
                         if (!is_link($dir_name . $file)) {
                             //--
                             if (is_dir($dir_name . $file)) {
                                 //-- dir
                                 if ($tmp_allow_addition) {
                                     //--
                                     $tmp_fsize = Smart::format_number_int(@filesize($dir_name . $file), '+');
                                     //--
                                     $this->num_dirs++;
                                     $this->num_size += $tmp_fsize;
                                     $this->num_dirs_size += $tmp_fsize;
                                     //--
                                     $tmp_fsize = 0;
                                     //--
                                     if ($tmp_add_pattern) {
                                         if ($recurring) {
                                             // if recurring, add the full path
                                             $this->pattern_dir_matches[$dir_name . $file] = @filemtime($dir_name . $file);
                                         } else {
                                             // if not recurring, add just base path, without dirname prefix
                                             $this->pattern_dir_matches[$file] = @filemtime($dir_name . $file);
                                         }
                                         //end if else
                                     }
                                     //end if
                                     //--
                                 }
                                 //end if
                                 //--
                                 if ($recurring) {
                                     //-- we go search inside even if this folder name may not match the search pattern, it is a folder, except if dissalow addition from above
                                     $this->folder_iterator($recurring, SmartFileSysUtils::add_dir_last_slash($dir_name . $file), $include_dot_files, $search_pattern, $search_prevent_file, $search_prevent_override);
                                     //--
                                 }
                                 //end if
                                 //--
                             } else {
                                 //-- file
                                 if ($tmp_allow_addition) {
                                     //--
                                     $tmp_fsize = Smart::format_number_int(@filesize($dir_name . $file), '+');
                                     //--
                                     $this->num_files++;
                                     $this->num_size += $tmp_fsize;
                                     $this->num_files_size += $tmp_fsize;
                                     //--
                                     $tmp_fsize = 0;
                                     //--
                                     if ($tmp_add_pattern) {
                                         if ($recurring) {
                                             // if recurring, add the full path
                                             $this->pattern_file_matches[$dir_name . $file] = @filemtime($dir_name . $file);
                                         } else {
                                             // if not recurring, add just base path, without dirname prefix
                                             $this->pattern_file_matches[$file] = @filemtime($dir_name . $file);
                                         }
                                         //end if else
                                     }
                                     //end if
                                     //--
                                 }
                                 //end if
                                 //--
                             }
                             //end else
                             //--
                         } else {
                             //-- link
                             if ($tmp_allow_addition) {
                                 //--
                                 $link_result = SmartFileSystem::link_get_origin($dir_name . $file);
                                 //--
                                 if (empty($link_result) or (string) $link_result == '' or !SmartFileSystem::file_or_link_exists($link_result)) {
                                     //--
                                     // case of readlink error ..., not includding broken links, they are useless
                                     //--
                                 } else {
                                     //--
                                     $tmp_size_arr = array();
                                     $tmp_fsize = 0;
                                     //$tmp_size_arr = (array) @lstat($dir_name.$file);
                                     //$tmp_fsize = Smart::format_number_int($tmp_size_arr[7],'+'); // $tmp_size_arr[7] -> size, but may break compare if on a different file system or in distributed storage on various OS
                                     //--
                                     $this->num_links++;
                                     //--
                                     if (file_exists($dir_name . $file)) {
                                         // here file_exists must be tested because if broken link not stat on it (filemtime) to avoid log un-necessary errors
                                         //-- bugfix: not if broken link
                                         $this->num_size += $tmp_fsize;
                                         if ($tmp_add_pattern) {
                                             if (is_dir($dir_name . $file)) {
                                                 $this->num_dirs++;
                                                 $this->num_dirs_size += $tmp_fsize;
                                                 if ($recurring) {
                                                     // if recurring, add the full path
                                                     $this->pattern_dir_matches[$dir_name . $file] = @filemtime($dir_name . $file);
                                                 } else {
                                                     // if not recurring, add just base path, without dirname prefix
                                                     $this->pattern_dir_matches[$file] = @filemtime($dir_name . $file);
                                                 }
                                                 //end if else
                                             } else {
                                                 $this->num_files++;
                                                 $this->num_files_size += $tmp_fsize;
                                                 if ($recurring) {
                                                     // if recurring, add the full path
                                                     $this->pattern_file_matches[$dir_name . $file] = @filemtime($dir_name . $file);
                                                 } else {
                                                     // if not recurring, add just base path, without dirname prefix
                                                     $this->pattern_file_matches[$file] = @filemtime($dir_name . $file);
                                                 }
                                                 //end if else
                                             }
                                             //end if else
                                         }
                                         //end if
                                         //--
                                     }
                                     //end if
                                     //--
                                     $tmp_fsize = 0;
                                     $tmp_size_arr = array();
                                     //--
                                 }
                                 //end if else
                                 //--
                             }
                             //end if
                             //--
                         }
                         //end if else
                         //--
                     }
                     //end if
                     //--
                 }
                 //end if(. ..)
                 //--
             }
             //end while
             //---------------------------------------
             @closedir($handle);
             //---------------------------------------
         } else {
             //---------------------------------------
             $this->errors_arr[] = $dir_name;
             //---------------------------------------
         }
         //end else
         //--
     } else {
         //---------------------------------------
         // nothing ...
         //---------------------------------------
     }
     //end if else
     //--
 }
 /**
  * MySQL Query :: Write.
  * This function is intended to be used for write type queries: BEGIN (TRANSACTION) ; COMMIT ; ROLLBACK ; INSERT ; INSERT IGNORE ; REPLACE ; UPDATE ; CREATE SCHEMAS ; CALLING STORED PROCEDURES ...
  *
  * @param STRING $queryval						:: the query
  * @param STRING $params_or_title 				:: *optional* array of parameters or query title for easy debugging
  * @param RESOURCE $y_connection				:: the connection
  * @return ARRAY 								:: [0 => 'control-message', 1 => #affected-rows]
  */
 public static function write_data($queryval, $params_or_title = '', $y_connection = 'DEFAULT')
 {
     //==
     $y_connection = self::check_connection($y_connection, 'WRITE-DATA');
     //==
     //-- samples
     // $queryval = 'BEGIN'; // start transaction
     // $queryval = 'UPDATE `tablename` SET `field` = \'value\' WHERE (`id_field` = \'val1\')';
     // $queryval = 'INSERT INTO `tablename` (`desiredfield1`, `desiredfield2`) VALUES (\'val1\', \'val2\')';
     // $queryval = 'DELETE FROM `tablename` WHERE (`id_field` = \'val1\')';
     // $queryval = 'COMMIT'; // commit transaction (on success)
     // $queryval = 'ROLLBACK'; // rollback transaction (on error)
     //--
     //--
     $time_start = 0;
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         $time_start = microtime(true);
     }
     //end if
     //--
     //--
     $use_param_query = false;
     if (is_array($params_or_title)) {
         if (Smart::array_size($params_or_title) > 0) {
             $use_param_query = true;
         }
         //end if
     }
     //end if
     //--
     if ($use_param_query === true) {
         $the_query_title = '';
         $queryval = self::prepare_param_query($queryval, (array) $params_or_title, $y_connection);
     } else {
         $the_query_title = (string) $params_or_title;
     }
     //end if else
     //--
     $result = @mysqli_query($y_connection, $queryval, MYSQLI_STORE_RESULT);
     $chk = @mysqli_errno($y_connection);
     $err = @mysqli_error($y_connection);
     //--
     //--
     $error = '';
     $affected = 0;
     if ($chk !== 0) {
         $error = 'Query FAILED:' . "\n" . $err;
     } else {
         $affected = @mysqli_affected_rows($y_connection);
     }
     //end if else
     //--
     //--
     $time_end = 0;
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         $time_end = (double) (microtime(true) - (double) $time_start);
     }
     //end if
     //--
     //--
     if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'mysqli|total-queries', 1, '+');
         //--
         SmartFrameworkRegistry::setDebugMsg('db', 'mysqli|total-time', $time_end, '+');
         //--
         if (is_array($params_or_title)) {
             $dbg_query_params = (array) $params_or_title;
         } else {
             $dbg_query_params = '';
         }
         //end if else
         //--
         if (strtoupper(substr(trim($queryval), 0, 5)) == 'BEGIN' or strtoupper(substr(trim($queryval), 0, 6)) == 'COMMIT' or strtoupper(substr(trim($queryval), 0, 8)) == 'ROLLBACK') {
             SmartFrameworkRegistry::setDebugMsg('db', 'mysqli|log', ['type' => 'transaction', 'data' => 'TRANSACTION :: ' . $the_query_title, 'query' => $queryval, 'params' => '', 'time' => Smart::format_number_dec($time_end, 9, '.', ''), 'connection' => (string) self::get_connection_id($y_connection)]);
         } elseif (strtoupper(substr(trim($queryval), 0, 4)) == 'SET ') {
             SmartFrameworkRegistry::setDebugMsg('db', 'mysqli|log', ['type' => 'set', 'data' => 'SET :: ' . $the_query_title, 'query' => $queryval, 'params' => $dbg_query_params, 'time' => Smart::format_number_dec($time_end, 9, '.', ''), 'connection' => (string) self::get_connection_id($y_connection)]);
         } else {
             SmartFrameworkRegistry::setDebugMsg('db', 'mysqli|log', ['type' => 'write', 'data' => 'WRITE :: ' . $the_query_title, 'query' => $queryval, 'params' => $dbg_query_params, 'rows' => $affected, 'time' => Smart::format_number_dec($time_end, 9, '.', ''), 'connection' => (string) self::get_connection_id($y_connection)]);
         }
         //end if else
         //--
     }
     //end if
     //--
     //--
     if (strlen($error) > 0) {
         //--
         $message = 'errorsqlwriteoperation: ' . $error;
         //--
         self::error(self::get_connection_id($y_connection), 'WRITE-DATA', $error, $queryval, $params_or_title);
         return array($message, 0);
         //--
     } else {
         //--
         $message = 'oksqlwriteoperation';
         // this can be extended to detect extra notices
         //--
     }
     //end else
     //--
     //--
     if ($result instanceof mysqli_result) {
         @mysqli_free_result($result);
     }
     //end if
     //--
     //--
     return array($message, Smart::format_number_int($affected, '+'));
     //--
 }
 /**
  * Function: JS Init JS-UI Tabs
  *
  * @access 		private
  * @internal
  *
  */
 public static function js_ajx_tabs_init($y_id_of_tabs, $y_selected = 0, $y_prevent_reload = false)
 {
     //--
     $y_selected = Smart::format_number_int($y_selected, '+');
     //--
     if ($y_prevent_reload === true) {
         $prevreload = 'true';
     } else {
         $prevreload = 'false';
     }
     //end if else
     //--
     return '<script type="text/javascript">try { SmartJS_BrowserUIUtils.Tabs_Init(\'' . Smart::escape_js($y_id_of_tabs) . '\', ' . $y_selected . ', ' . $prevreload . '); } catch(e) { console.log(\'Failed to initialize JS-UI Tabs: \' + e); }</script>';
     //--
 }
    /**
     * PgSQL Query :: Write Ignore - Catch Duplicate Key Violation or Foreign Key Violation Errors (This is the equivalent of MySQL's INSERT IGNORE / UPDATE IGNORE / DELETE IGNORE, but it can catch UNIQUE violations on both: INSERT / UPDATE / DELETE statements and also can catch FOREIGN KEY violations).
     * This function is intended to be used only for write type queries like: INSERT / UPDATE / DELETE which can be ignored if unique violations or foreign key violations and will return the # of affected rows or zero if an exception raised.
     * The catch of PostgreSQL exceptions is handled completely by this function so there is no need for a catch errors outside.
     *
     * IMPORTANT:
     * This function needs the pgsql notice message tracking enabled in PHP (not ignored); This must be set in php.ini (pgsql.ignore_notice = 0).
     * The internal mechanism of this function to catch UNIQUE or FOREIGN KEYS violations is that the EXCEPTIONS are catch at the PostgreSQL level in a DO block.
     * This is the best approach to handle safe UPSERT or INSERT IGNORE / UPDATE IGNORE / DELETE IGNORE like queries in high load envionments or to avoid fatal errors when a INSERT / UPDATE / DELETE violates a unique key or a foreign key with PostgreSQL.
     * This function can be used inside transactions blocks but never use this function to execute statements as: BEGIN, START TRANSACTION, COMMIT, ROLLBACK or SET statements, as the context is incompatible.
     * HINTS:
     * On PostgreSQL 9.5/later there is an alternative which can be used directly with write_data() without the need of this function as the following statement: INSERT ... ON CONFLICT DO NOTHING/UPDATE ... (as the equivalent of INSERT IGNORE / UPSERT), but the following statements are still missing (not implemented): UPDATE ... ON CONFLICT DO NOTHING / DELETE ... ON CONFLICT DO NOTHING .
     * This function will remain in the future to offer backward compatibility with PostgreSQL 8.4 ... 9.5 even if PostgreSQL at some moment will have ON CONFLICT DO implemented for all 3 INSERT / UPDATE / DELETE.
     *
     * @param STRING $queryval						:: the query
     * @param STRING $params_or_title 				:: *optional* array of parameters ($1, $2, ... $n) or query title for easy debugging
     * @param RESOURCE $y_connection				:: the connection
     * @return ARRAY 								:: [0 => 'control-message', 1 => #affected-rows]
     */
    public static function write_igdata($queryval, $params_or_title = '', $y_connection = 'DEFAULT')
    {
        //==
        $y_connection = self::check_connection($y_connection, 'WRITE-IG-DATA');
        //==
        //-- samples
        // $queryval = 'UPDATE "tablename" SET "field" = \'value\' WHERE ("id_field" = \'val1\')';
        // $queryval = 'INSERT INTO "tablename" ("desiredfield1", "desiredfield2") VALUES (\'val1\', \'val2\')';
        //--
        // ##### 'pgsql.ignore_notice' must be set to 0 in PHP.INI (checked via connect) #####
        //--
        /* PRE-CHECK (DO NOT ALLOW IN TRANSACTION BLOCKS) - No More Necessary !!, now can be safe used also in transactions as the exceptions are catch in the DO block
        	$transact_status = @pg_transaction_status($y_connection);
        	if(($transact_status === PGSQL_TRANSACTION_INTRANS) OR ($transact_status === PGSQL_TRANSACTION_INERROR)) {
        		self::error($y_connection, 'WRITE-IG-DATA', 'ERROR: Write Ignore cannot be used inside Transaction Blocks ...', $queryval, '');
        		return array('errortransact: '.'Write Ignore cannot be used inside Transaction Blocks', 0);
        	} //end if
        	*/
        //--
        //--
        $time_start = 0;
        if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
            $time_start = microtime(true);
        }
        //end if
        //--
        //--
        $use_param_query = false;
        if (strpos((string) $queryval, '$') !== false and Smart::array_size($params_or_title) > 0) {
            $use_param_query = true;
        }
        //end if
        //--
        if ($use_param_query === true) {
            $the_query_title = '';
        } else {
            $the_query_title = (string) $params_or_title;
        }
        //end if else
        //--
        //--
        /* At the moment, in PgSQL 9.5 only works ON CONFLICT DO NOTHING for INSERT (for UPDATE statements fails ...)
        	if(version_compare(self::check_server_version($y_connection), '9.6') >= 0) {
        		//--
        		$xmode = 'affected';
        		$vmode = '[ON CONFLICT DO NOTHING]';
        		//--
        		$prep_query = (string) $queryval.' ON CONFLICT DO NOTHING'; // fix for PostgreSQL >= 9.5 :: RETURNING *
        		//--
        		if($use_param_query === true) {
        			$result = @pg_query_params($y_connection, $prep_query, $params_or_title); // NOTICE: parameters are only allowed in ONE command not combined statements
        		} else {
        			$result = @pg_query($y_connection, $prep_query);
        		} //end if else
        		//--
        	} else {
        	*/
        //--
        if ((string) ini_get('pgsql.ignore_notice') != '0') {
            // {{{SYNC-PGSQL-NOTIF-CHECK}}}
            self::error($y_connection, 'WRITE-IG-DATA', 'Check PgSQL PHP.INI Settings', 'SETTINGS: PostgreSQL Notifications need to be ENABLED in PHP.INI !', 'SET in PHP.INI this: pgsql.ignore_notice = 0');
            return array('errorinits: PostgreSQL Notifications need to be ENABLED in PHP.INI', 0);
        }
        //end if
        //--
        $xmode = 'notice';
        $vmode = '[Catch EXCEPTION on Violations for: Unique / Foreign Key]';
        //--
        if ($use_param_query === true) {
            $queryval = (string) self::prepare_param_query((string) $queryval, (array) $params_or_title, $y_connection);
        }
        //end if
        //--
        $unique_id = 'WrIgData_PgSQL_' . Smart::uuid_10_seq() . '_' . Smart::uuid_10_str() . '_' . Smart::uuid_10_num() . '_' . sha1(SmartUtils::client_ident_private_key()) . '_' . sha1(SmartUtils::get_visitor_tracking_uid() . ':' . Smart::uuid_36('pgsql-write-ig') . ':' . Smart::uuid_45('pgsql-write-ig')) . '_Func';
        // this must be a unique that cannot guess to avoid dollar escaping injections
        //--
        $prep_query = (string) '
	DO LANGUAGE plpgsql
	$' . $unique_id . '$
	DECLARE affected_rows BIGINT;
	BEGIN
		-- do the query an safe catch exceptions (unique key, foreign key)
			affected_rows := 0;
	' . "\t\t" . trim(rtrim($queryval, ';')) . ';' . '
			GET DIAGNOSTICS affected_rows = ROW_COUNT;
			RAISE NOTICE \'SMART-FRAMEWORK-PGSQL-NOTICE: AFFECTED ROWS #%\', affected_rows;
			RETURN;
		EXCEPTION
			WHEN unique_violation THEN RAISE NOTICE \'SMART-FRAMEWORK-PGSQL-NOTICE: AFFECTED ROWS #0\';
			WHEN foreign_key_violation THEN RAISE NOTICE \'SMART-FRAMEWORK-PGSQL-NOTICE: AFFECTED ROWS #0\'; -- this is a different behaviour than ON CONFLICT DO NOTHING in PgSQL 9.5 or later versions ...
	END
	$' . $unique_id . '$;
	';
        //--
        $result = @pg_query($y_connection, $prep_query);
        //--
        //} //end if else
        //--
        //--
        $error = '';
        $affected = 0;
        if (!$result) {
            $error = 'Query FAILED:' . "\n" . @pg_last_error($y_connection);
        } else {
            //if((string)$xmode == 'notice') {
            $affected = (int) self::get_notice_smart_affected_rows(@pg_last_notice($y_connection));
            // in this case we can only monitor affected rows via a custom notice (the only possible way to return something from anonymous pgsql functions ...)
            //} else { // affected
            //	$affected = @pg_affected_rows($result); // for PostgreSQL >= 9.5
            //} //end if else
        }
        //end if else
        //--
        //--
        $time_end = 0;
        if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
            $time_end = (double) (microtime(true) - (double) $time_start);
        }
        //end if
        //--
        //--
        if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') {
            //--
            SmartFrameworkRegistry::setDebugMsg('db', 'pgsql|total-queries', 1, '+');
            //--
            SmartFrameworkRegistry::setDebugMsg('db', 'pgsql|total-time', $time_end, '+');
            //--
            $dbg_query_params = '';
            //--
            if (strtoupper(substr(trim($queryval), 0, 5)) == 'BEGIN' or strtoupper(substr(trim($queryval), 0, 17)) == 'START TRANSACTION' or strtoupper(substr(trim($queryval), 0, 6)) == 'COMMIT' or strtoupper(substr(trim($queryval), 0, 8)) == 'ROLLBACK') {
                // ERROR
                self::error($y_connection, 'WRITE-IG-DATA ' . $vmode, 'ERROR: This function cannot handle TRANSACTION Specific Statements ...', $queryval, $the_query_title);
                return array('errorsqlstatement: ' . 'This function cannot handle TRANSACTION Specific Statements', 0);
            } elseif (strtoupper(substr(trim($queryval), 0, 4)) == 'SET ') {
                // ERROR
                self::error($y_connection, 'WRITE-IG-DATA ' . $vmode, 'ERROR: This function cannot handle SET Statements ...', $queryval, $the_query_title);
                return array('errorsqlstatement: ' . 'This function cannot handle SET Statements', 0);
            } else {
                SmartFrameworkRegistry::setDebugMsg('db', 'pgsql|log', ['type' => 'write', 'data' => 'WRITE / IGNORE ' . $vmode . ' :: ' . $the_query_title, 'query' => $queryval, 'params' => $dbg_query_params, 'rows' => $affected, 'time' => Smart::format_number_dec($time_end, 9, '.', ''), 'connection' => (string) $y_connection]);
            }
            //end if else
            //--
        }
        //end if
        //--
        //--
        if (strlen($error) > 0) {
            //--
            $message = 'errorsqlwriteoperation: ' . $error;
            //--
            self::error($y_connection, 'WRITE-IG-DATA ' . $vmode, $error, $queryval, $the_query_title);
            return array($message, 0);
            //--
        } else {
            //--
            $record = @pg_fetch_row($result);
            //--
            $message = 'oksqlwriteoperation';
            // this can be extended to detect extra notices
            //--
        }
        //end else
        //--
        //--
        if (is_resource($result)) {
            // check in case of error
            @pg_free_result($result);
        }
        //end if
        //--
        //--
        return array($message, Smart::format_number_int($affected, '+'));
        //--
    }