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: { ' . 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: { ' . 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 <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);') . ' ' . '<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, '+')); //-- }