Пример #1
0
 public static final function DownloadsHandler($encrypted_download_pack, $controller_key)
 {
     //--
     $encrypted_download_pack = (string) $encrypted_download_pack;
     $controller_key = (string) $controller_key;
     //--
     $client_signature = SmartUtils::get_visitor_signature();
     //--
     if ((string) SMART_APP_VISITOR_COOKIE == '') {
         Smart::log_info('File Download', 'Failed: 400 / Invalid Visitor Cookie' . ' on Client: ' . $client_signature);
         self::Raise400Error('ERROR: Invalid Visitor UUID. Cookies must be enabled to enable this feature !');
         return '';
     }
     //end if
     //--
     $downloaded_file = '';
     // init
     //--
     $decoded_download_packet = (string) trim((string) SmartUtils::crypto_decrypt((string) $encrypted_download_pack, 'SmartFramework//DownloadLink' . SMART_FRAMEWORK_SECURITY_KEY));
     //--
     if ((string) $decoded_download_packet != '') {
         // if data is corrupted, decrypt checksum does not match, will return an empty string
         //--
         if (SMART_FRAMEWORK_ADMIN_AREA === true) {
             // {{{SYNC-DWN-CTRL-PREFIX}}}
             $controller_key = (string) 'AdminArea/' . $controller_key;
         } else {
             $controller_key = (string) 'IndexArea/' . $controller_key;
         }
         //end if
         //-- {{{SYNC-DOWNLOAD-ENCRYPT-ARR}}}
         $arr_metadata = explode("\n", (string) $decoded_download_packet, 6);
         // only need first 5 parts
         //print_r($arr_metadata);
         // #PACKET-STRUCTURE# [we will have an array like below, according with the: SmartUtils::create_download_link()]
         // [TimedAccess]\n
         // [FilePath]\n
         // [AccessKey]\n
         // [UniqueKey]\n
         // [SFR.UA]\n
         // #END#
         //--
         $crrtime = (string) trim((string) $arr_metadata[0]);
         $filepath = (string) trim((string) $arr_metadata[1]);
         $access_key = (string) trim((string) $arr_metadata[2]);
         $unique_key = (string) trim((string) $arr_metadata[3]);
         //--
         unset($arr_metadata);
         //--
         $timed_hours = 1;
         // default expire in 1 hour
         if (defined('SMART_FRAMEWORK_DOWNLOAD_EXPIRE')) {
             if ((int) SMART_FRAMEWORK_DOWNLOAD_EXPIRE > 0) {
                 if ((int) SMART_FRAMEWORK_DOWNLOAD_EXPIRE <= 24) {
                     // max is 24 hours (since download link is bind to unique browser signature + unique cookie ... make non-sense to keep more)
                     $timed_hours = (int) SMART_FRAMEWORK_DOWNLOAD_EXPIRE;
                 }
                 //end if
             }
             //end if
         }
         //end if
         //--
         if ((int) $timed_hours > 0) {
             if ((int) $crrtime < (int) (time() - 60 * 60 * $timed_hours)) {
                 Smart::log_info('File Download', 'Failed: 403 / Download expired at: ' . date('Y-m-d H:i:s O', (int) $crrtime) . ' for: ' . $filepath . ' on Client: ' . $client_signature);
                 self::Raise403Error('ERROR: The Access Key for this Download is Expired !');
                 return '';
             }
             //end if
         }
         //end if
         //--
         if ((string) $access_key != (string) sha1('DownloadLink:' . SMART_SOFTWARE_NAMESPACE . '-' . SMART_FRAMEWORK_SECURITY_KEY . '-' . SMART_APP_VISITOR_COOKIE . ':' . $filepath . '^' . $controller_key)) {
             Smart::log_info('File Download', 'Failed: 403 / Invalid Access Key for: ' . $filepath . ' on Client: ' . $client_signature);
             self::Raise403Error('ERROR: Invalid Access Key for this Download !');
             return '';
         }
         //end if
         //--
         if ((string) $unique_key != (string) SmartHashCrypto::sha1('Time=' . $crrtime . '#' . SMART_SOFTWARE_NAMESPACE . '-' . SMART_FRAMEWORK_SECURITY_KEY . '-' . $access_key . '-' . SmartUtils::unique_auth_client_private_key() . ':' . $filepath . '+' . $controller_key)) {
             Smart::log_info('File Download', 'Failed: 403 / Invalid Client (Unique) Key for: ' . $filepath . ' on Client: ' . $client_signature);
             self::Raise403Error('ERROR: Invalid Client Key to Access this Download !');
             return '';
         }
         //end if
         //--
         if (SmartFileSysUtils::check_file_or_dir_name($filepath)) {
             //--
             $skip_log = 'no';
             // default log
             if (defined('SMART_FRAMEWORK_DOWNLOAD_SKIP_LOG')) {
                 $skip_log = 'yes';
                 // do not log if accessed via admin area and user is authenticated
             }
             //end if
             //--
             $tmp_file_ext = (string) strtolower(SmartFileSysUtils::get_file_extension_from_path($filepath));
             // [OK]
             $tmp_file_name = (string) strtolower(SmartFileSysUtils::get_file_name_from_path($filepath));
             //--
             $tmp_eval = SmartFileSysUtils::mime_eval($tmp_file_name);
             $mime_type = (string) $tmp_eval[0];
             $mime_disp = (string) $tmp_eval[1];
             //-- the path must not start with / but this is tested below
             $tmp_arr_paths = (array) explode('/', $filepath, 2);
             // only need 1st part for testing
             //-- allow file downloads just from specific folders like wpub/ or wsys/ (this is a very important security fix to dissalow any downloads that are not in the specific folders)
             if (substr((string) $filepath, 0, 1) != '/' and strpos((string) SMART_FRAMEWORK_DOWNLOAD_FOLDERS, '<' . trim((string) $tmp_arr_paths[0]) . '>') !== false and stripos((string) SMART_FRAMEWORK_DENY_UPLOAD_EXTENSIONS, '<' . $tmp_file_ext . '>') === false) {
                 //--
                 SmartFileSysUtils::raise_error_if_unsafe_path($filepath);
                 // re-test finally
                 //--
                 @clearstatcache();
                 //--
                 if (is_file($filepath)) {
                     //--
                     if (!headers_sent()) {
                         //--
                         $fp = @fopen($filepath, 'rb');
                         $fsize = @filesize($filepath);
                         //--
                         if (!$fp || $fsize <= 0) {
                             //--
                             Smart::log_info('File Download', 'Failed: 404 / The requested File is Empty or Not Readable: ' . $filepath . ' on Client: ' . $client_signature);
                             self::Raise404Error('WARNING: The requested File is Empty or Not Readable !');
                             return '';
                             //--
                         }
                         //end if
                         //-- set max execution time to zero
                         ini_set('max_execution_time', 0);
                         // we can expect a long time if file is big, but this will be anyway overriden by the WebServer Timeout Directive
                         //--
                         // cache headers are presumed to be sent by runtime before of this step
                         //--
                         header('Content-Type: ' . $mime_type);
                         header('Content-Disposition: ' . $mime_disp);
                         header('Content-Length: ' . $fsize);
                         //--
                         @fpassthru($fp);
                         // output without reading all in memory
                         //--
                         @fclose($fp);
                         //--
                     } else {
                         //--
                         Smart::log_info('File Download', 'Failed: 500 / Headers Already Sent: ' . $filepath . ' on Client: ' . $client_signature);
                         self::Raise500Error('ERROR: Download Failed, Headers Already Sent !');
                         return '';
                         //--
                     }
                     //end if else
                     //--
                     if ((string) $skip_log != 'yes') {
                         //--
                         $downloaded_file = (string) $filepath;
                         // return the file name to be logged
                         //--
                     }
                     //end if
                     //--
                 } else {
                     //--
                     Smart::log_info('File Download', 'Failed: 404 / The requested File does not Exists: ' . $filepath . ' on Client: ' . $client_signature);
                     self::Raise404Error('WARNING: The requested File for Download does not Exists !');
                     return '';
                     //--
                 }
                 //end if else
             } else {
                 //--
                 Smart::log_info('File Download', 'Failed: 403 / Access to this File is Denied: ' . $filepath . ' on Client: ' . $client_signature);
                 self::Raise403Error('ERROR: Download Access to this File is Denied !');
                 return '';
                 //--
             }
             //end if else
             //--
         } else {
             //--
             Smart::log_info('File Download', 'Failed: 400 / Unsafe File Path: ' . $filepath . ' on Client: ' . $client_signature);
             self::Raise400Error('ERROR: Unsafe Download File Path !');
             return '';
             //--
         }
         //end if else
         //--
     } else {
         //--
         Smart::log_info('File Download', 'Failed: 400 / Invalid Data Packet' . ' on Client: ' . $client_signature);
         self::Raise400Error('ERROR: Invalid Download Data Packet !');
         return '';
         //--
     }
     //end if else
     //--
     return (string) $downloaded_file;
     //--
 }
Пример #2
0
 private static function read_mime_message($y_enc_msg_file, $y_ctrl_key, $y_process_mode, $y_show_headers, $y_title, $y_link, $y_target)
 {
     // $y_process_mode : 'default' | 'print' | 'data-full' | 'data-reply'
     // $y_show_headers : 'default' | 'subject' (just for mode: 'default' | 'print')
     //--
     $msg_decode_arr = (array) self::decode_mime_fileurl((string) $y_enc_msg_file, (string) $y_ctrl_key);
     //--
     if ((string) $msg_decode_arr['error'] != '') {
         Smart::raise_error('ERROR: MIME Parser // Mesage File Decode: ' . $msg_decode_arr['error'], 'ERROR: MIME Parser // Mesage File Decode // See error log for details ...');
         return '';
     }
     //end if
     //--
     //--
     $the_message_eml = (string) trim((string) $msg_decode_arr['message-file']);
     $the_part_id = (string) trim((string) $msg_decode_arr['message-part']);
     //--
     //--
     if ((string) $the_message_eml == '' or !is_file((string) $the_message_eml)) {
         Smart::raise_error('ERROR: MIME Parser // Message File EMPTY or NOT FOUND !: ' . $the_message_eml, 'ERROR: MIME Parser // Mesage File Decode // See error log for details ...');
         return '';
     }
     //end if
     //--
     if (substr((string) $the_message_eml, -4, 4) != '.eml') {
         Smart::raise_error('ERROR: MIME Parser // Message File Extension is not .eml !: ' . $the_message_eml, 'ERROR: MIME Parser // Mesage File Decode // See error log for details ...');
         return '';
     }
     //end if
     //--
     //--
     $out = '';
     // init
     $reply_text = array();
     // init
     //--
     //==
     //--
     $content = SmartFileSystem::read((string) $the_message_eml);
     $eml = new SmartMailerMimeDecode();
     $head = $eml->get_header(SmartUnicode::sub_str((string) $content, 0, 65535));
     // some messages fail with 8192 to decode ; a faster compromise would be 16384, but here we can use a higher value since is done once (text 65535)
     $msg = $eml->get_bodies((string) $content, (string) $the_part_id);
     unset($eml);
     unset($content);
     //--
     //==
     //--
     $reg_atts_num = 0;
     $reg_atts_list = '';
     // list separed by \n
     //--
     if (strlen($the_part_id) <= 0) {
         //-- display whole message
         $reg_is_part = 'no';
         $skip_part_processing = 'no';
         $skip_part_linking = 'no';
         //--
     } else {
         //-- display only a part of the message
         $reg_is_part = 'yes';
         $skip_part_processing = 'no';
         $skip_part_linking = 'yes';
         //--
         if (substr($the_part_id, 0, 4) == 'txt_') {
             //-- text part
             $tmp_part = $msg['texts'][$the_part_id];
             $msg = array();
             $msg['texts'][$the_part_id] = (array) $tmp_part;
             unset($tmp_part);
             //--
         } else {
             //-- att / cid part
             $skip_part_processing = 'yes';
             //--
             if (!is_array($msg['attachments'][$the_part_id])) {
                 // try to normalize name
                 $the_part_id = trim(str_replace(' ', '', $the_part_id));
             }
             //end if
             //--
             $out = (string) $msg['attachments'][$the_part_id]['content'];
             // DO NO MORE ADD ANYTHING TO $out ... downloading, there are no risk of code injection
             //--
         }
         //end if else
         //--
     }
     //end if else
     //--
     //--
     if ((string) $y_process_mode == 'print') {
         $skip_part_linking = 'yes';
         // skip links to other sub-parts like texts / attachments but not cids !
     } elseif ((string) $y_process_mode == 'data-reply') {
         $skip_part_linking = 'yes';
     }
     //end if
     //--
     //--
     if ((string) $skip_part_processing != 'yes') {
         //--
         if ((string) $y_title != '') {
             $out .= (string) $y_title;
             // expects '' or valid HTML
         }
         //end if
         //--
         $out .= '<!-- Smart.Framework // MIME MESSAGE HTML --><div align="left"><div id="mime_msg_box">';
         //--
         if (strlen($the_part_id) <= 0) {
             //--
             $priority_img = '';
             switch ((string) $head['priority']) {
                 case '1':
                     // high
                     $priority_img = '<img src="lib/core/plugins/img/email/priority_high.png" align="left" alt="High Priority" title="High Priority">';
                     break;
                 case '5':
                     // low
                     $priority_img = '<img src="lib/core/plugins/img/email/priority_low.png" align="left" alt="Low Priority" title="Low Priority">';
                     break;
                 case '3':
                     // medium
                 // medium
                 default:
                     $priority_img = '';
                     //$priority_img = '<img src="lib/core/plugins/img/email/priority_normal.png" align="left" alt="Normal Priority" title="Normal Priority">';
             }
             //end switch
             //--
             if ((string) $skip_part_linking != 'yes') {
                 // avoid display the print link when only a part is displayed
                 $out .= '<a href="' . self::mime_link($y_ctrl_key, $the_message_eml, $the_part_id, $y_link, $eval_arr[0], $eval_arr[1], 'print') . '" target="' . $y_target . '__mimepart" data-smart="open.modal">' . '<img align="right" src="lib/core/img/buttons/bttn_print.png">' . '</a>';
             }
             //end if
             //--
             switch ((string) $y_show_headers) {
                 case 'subject':
                     //--
                     if ((string) $head['subject'] != '[?]') {
                         $out .= '<h1><font size="4">' . Smart::escape_html($head['subject']) . '</font></h1><br>';
                     }
                     //end if
                     //--
                     break;
                 case 'default':
                 default:
                     //--
                     if ((string) $head['subject'] != '[?]') {
                         $out .= '<h1><font size="4">&nbsp;' . Smart::escape_html($head['subject']) . '</font>' . $priority_img . '</h1><hr>';
                     }
                     //end if
                     //--
                     if ((string) $head['date'] != '(?)') {
                         $out .= '<font size="3"><b>Date:</b> ' . Smart::escape_html(date('Y-m-d H:i:s O', @strtotime($head['date']))) . '</font><br>';
                     }
                     //end if
                     //--
                     $out .= '<font size="2"><b>From:</b> ' . Smart::escape_html($head['from_addr']) . ' &nbsp; <i>' . Smart::escape_html($head['from_name']) . '</i>' . '</font><br>';
                     $out .= '<font size="2"><b>To:</b> ' . Smart::escape_html($head['to_addr']) . ' &nbsp; <i>' . Smart::escape_html($head['to_name']) . '</i>' . '</font><br>';
                     //--
                     if (strlen($head['cc_addr']) > 0) {
                         $out .= '<font size="2"><b>Cc:</b> ';
                         if (SmartUnicode::str_contains($head['cc_addr'], ',')) {
                             $arr_cc_addr = (array) explode(',', (string) $head['cc_addr']);
                             $arr_cc_name = (array) explode(',', (string) $head['cc_name']);
                             $out .= '[@]';
                             for ($z = 0; $z < Smart::array_size($arr_cc_addr); $z++) {
                                 $out .= '<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' . Smart::escape_html(trim($arr_cc_addr[$z])) . ' &nbsp; <i>' . Smart::escape_html(trim($arr_cc_name[$z])) . '</i>';
                             }
                             //end for
                         } else {
                             $out .= Smart::escape_html($head['cc_addr']) . ' &nbsp; <i>' . Smart::escape_html($head['cc_name']) . '</i>';
                         }
                         //end if else
                         $out .= '</font><br>';
                     }
                     //end if
                     //--
                     if (strlen($head['bcc_addr']) > 0) {
                         $out .= '<font size="2"><b>Bcc:</b> ';
                         $out .= Smart::escape_html($head['bcc_addr']) . ' &nbsp; <i>' . Smart::escape_html($head['bcc_name']) . '</i>';
                         $out .= '</font><br>';
                     }
                     //end if
                     //--
             }
             //end switch
             //-- print attachments
             if (is_array($msg['attachments'])) {
                 //--
                 $cnt = 0;
                 //--
                 $atts = '';
                 // atts with link
                 $xatts = '';
                 // atts without link
                 //--
                 $tmp_att_img = '<img src="lib/core/plugins/img/email/attachment.png">';
                 //--
                 foreach ($msg['attachments'] as $key => $val) {
                     //--
                     $tmp_arr = array();
                     $tmp_arr = (array) $val;
                     //--
                     if ((string) $tmp_arr['mode'] == 'normal') {
                         //--
                         $cnt += 1;
                         //--
                         $eval_arr = SmartFileSysUtils::mime_eval((string) $tmp_arr['filename']);
                         $tmp_att_name = Smart::escape_html((string) $tmp_arr['filename']);
                         $tmp_att_size = Smart::escape_html((string) SmartUtils::pretty_print_bytes((int) $tmp_arr['filesize'], 1));
                         //--
                         $reg_atts_num += 1;
                         $reg_atts_list .= str_replace(array("\r", "\n", "\t"), array('', '', ''), (string) $tmp_arr['filename']) . "\n";
                         //--
                         $atts .= '<div align="left"><table border="0" cellpadding="2" cellspacing="0" title="Attachment #' . $cnt . '"><tr><td>' . $tmp_att_img . '</td><td>&nbsp;</td><td><a href="' . self::mime_link($y_ctrl_key, $the_message_eml, $key, $y_link, $eval_arr[0], $eval_arr[1]) . '" target="' . $y_target . '__mimepart" data-smart="open.modal"><font size="1"><b>' . $tmp_att_name . '</b></font></a></td><td><font size="1"> &nbsp;<b><i>' . $tmp_att_size . '</i></b></font></td></tr></table></div>';
                         $xatts .= '<div align="left">' . $tmp_att_img . '&nbsp;&nbsp;<font size="1">' . $tmp_att_name . '&nbsp;&nbsp;<i>' . $tmp_att_size . '</i></font></div>';
                         //--
                     }
                     //end if
                     //--
                 }
                 //end foreach
                 //--
                 if ($cnt > 0) {
                     if ((string) $skip_part_linking == 'yes') {
                         // avoid displaying attachments links when only a part is displayed
                         $out .= '<hr><div align="left">' . $xatts . '</div>';
                     } else {
                         $out .= '<hr><div align="left">' . $atts . '</div>';
                     }
                     //end if
                 }
                 //end if
                 //--
                 $tmp_att_name = '';
                 $tmp_att_size = '';
                 //--
                 $atts = '';
                 $xatts = '';
                 //--
             }
             //end if
             //--
         } else {
             //--
             $out .= '<div align="right"><font size="1">' . Smart::escape_html($head['subject']) . ' // ' . 'MIME Part ID : <i>' . Smart::escape_html($the_part_id) . '</i></font></div>';
             //--
         }
         //end if
         //-- print text bodies
         $markup_multipart = 'This is a multi-part message in MIME format.';
         if (is_array($msg['texts'])) {
             //-- check similarity and prepare the HTML parts
             $buff = '';
             $buff_id = '';
             $xbuff = '';
             $xbuff_id = '';
             $skips = array();
             $numparts = 0;
             foreach ($msg['texts'] as $key => $val) {
                 //--
                 $numparts += 1;
                 //--
                 if ((string) $val['type'] == 'text') {
                     // assure we don't print other things
                     //--
                     if ((string) $val['mode'] == 'text/plain') {
                         // Plain TEXT
                         //-- sanitize text
                         $val['content'] = '<!-- MIMEREAD:PART:TEXT -->' . Smart::escape_html($val['content']);
                         $val['content'] = str_replace(array("\r\n", "\r", "\n"), array("\n", "\n", '<br>'), $val['content']);
                         $val['content'] = SmartParser::text_urls($val['content']);
                         //--
                         $msg['texts'][$key]['content'] = $val['content'];
                         // rewrite back
                         //-- assign buffer
                         $buff = SmartUnicode::sub_str($val['content'], 0, 16384);
                         $buff_id = $key;
                         //--
                         $percent_similar = 0;
                         if (strlen($the_part_id) <= 0) {
                             @similar_text($buff, $markup_multipart, $percent_similar);
                             if ($percent_similar >= 25) {
                                 // 25% at least similarity
                                 $skips[$buff_id] = $percent_similar;
                                 // skip this alternate html part ...
                             }
                             //end if
                         }
                         //end if
                         //--
                         // clean buffer
                         $xbuff = '';
                         $xbuff_id = '';
                         //--
                     } else {
                         // HTML Parts :: check similarity
                         //--
                         $val['content'] = '<!-- MIMEREAD:PART:HTML -->' . preg_replace("'" . '<\\?xml' . ".*?" . '>' . "'si", " ", (string) $val['content']);
                         // remove always fake "< ?" as "< ?xml" (fixed with /u modifier for unicode strings)
                         //--
                         if (SmartUnicode::str_contains($val['content'], '<' . '?') or SmartUnicode::str_contains($val['content'], '?' . '>') or SmartUnicode::str_contains($val['content'], '<' . '%') or SmartUnicode::str_contains($val['content'], '%' . '>')) {
                             //--
                             $val['content'] = @highlight_string($val['content'], 1);
                             // highlight the PHP* code & sanitize the parts
                             //--
                         } else {
                             //-- sanitize this html part
                             $val['content'] = (new SmartHtmlParser($val['content']))->get_clean_html();
                             //-- replace cid images
                             $tmp_matches = array();
                             preg_match_all('/<img[^>]+src=[\'"]?(cid:)([^\'"]*)[\'"]?[^>]*>/si', (string) $val['content'], $tmp_matches);
                             // fix: previous was just i (not si) ; modified on 160205
                             // $tmp_matches[0][i] : the full link
                             // $tmp_matches[1][i] : 'cid:'
                             // $tmp_matches[2][i] : cid part id
                             for ($cids = 0; $cids < Smart::array_size($tmp_matches[0]); $cids++) {
                                 $tmp_replace_cid_link = '';
                                 $tmp_replace_cid_link = (string) $tmp_matches[0][$cids];
                                 $tmp_replace_cid_link = str_replace("\n", ' ', $tmp_replace_cid_link);
                                 $tmp_replace_cid_link = str_replace($tmp_matches[1][$cids] . $tmp_matches[2][$cids], self::mime_link($y_ctrl_key, $the_message_eml, 'cid_' . $tmp_matches[2][$cids], $y_link, 'image', 'inline'), $tmp_replace_cid_link);
                                 //echo '<pre>'.Smart::escape_html($tmp_replace_cid_link).'</pre>';
                                 $val['content'] = str_replace($tmp_matches[0][$cids], $tmp_replace_cid_link, $val['content']);
                             }
                             //end for
                             $tmp_matches = array();
                             //--
                         }
                         //end if else
                         //--
                         $msg['texts'][$key]['content'] = $val['content'];
                         // rewrite back
                         //--
                         $xbuff = SmartUnicode::sub_str(Smart::striptags($val['content']), 0, 16384);
                         $xbuff_id = $key;
                         //--
                         $percent_similar = 0;
                         if (strlen($the_part_id) <= 0) {
                             @similar_text($buff, $xbuff, $percent_similar);
                             if ($percent_similar >= 15) {
                                 // 15% at least similarity
                                 $skips[$buff_id] = $percent_similar;
                                 // skip this alternate text part ...
                             }
                             //end if
                         }
                         //end if
                         //--
                         // clean buffer
                         $buff = '';
                         $buff_id = '';
                         //--
                     }
                     //end if
                     //--
                 }
                 //end if
                 //--
             }
             //end foreach
             //--
             if ($numparts <= 1) {
                 $skips = array();
                 // disallow skips if only one part
             }
             //end if
             //-- print bodies except the skipped by similarity
             $out .= '<hr>';
             //--
             $cnt = 0;
             foreach ($msg['texts'] as $key => $val) {
                 //--
                 if ((string) $val['type'] == 'text') {
                     // assure we don't print other things
                     //--
                     $cnt += 1;
                     //--
                     $eval_arr = array();
                     $eval_arr = SmartFileSysUtils::mime_eval('part_' . $cnt . '.html', 'inline');
                     //--
                     $tmp_link_pre = '<span title="Mime Part #' . $cnt . ' ( ' . Smart::escape_html(strtolower($val['mode']) . ' : ' . strtoupper($val['charset'])) . ' )"><a href="' . self::mime_link($y_ctrl_key, $the_message_eml, $key, $y_link, $eval_arr[0], $eval_arr[1], 'minimal') . '" target="' . $y_target . '__mimepart" data-smart="open.modal">';
                     $tmp_link_pst = '</a></span>';
                     //--
                     if (strlen($skips[$key]) <= 0) {
                         // print part if not skipped by similarity ...
                         //--
                         if ((string) $skip_part_linking == 'yes') {
                             // avoid display sub-text part links when only a part is displayed
                             $tmp_pict_img = '';
                         } else {
                             $tmp_pict_img = '<div align="right">' . $tmp_link_pre . '<img src="lib/framework/img/mark_right.gif">' . $tmp_link_pst . '</div>';
                         }
                         //end if
                         //--
                         if ((string) $y_process_mode == 'data-reply') {
                             if (strlen($reply_text['message']) <= 0) {
                                 $reply_text['message'] = (string) $val['content'];
                             }
                             //end if
                         } else {
                             $out .= $tmp_pict_img;
                             $out .= $val['content'];
                             $out .= '<br><hr><br>';
                         }
                         //end if
                         //--
                     } else {
                         //--
                         if ((string) $skip_part_linking != 'yes') {
                             // for replies, avoid display sub-text part links when only a part is displayed
                             if ((string) $y_process_mode == 'data-reply') {
                                 // nothing
                             } else {
                                 $out .= '<div align="right">' . '<span title="' . '~' . Smart::escape_html(Smart::format_number_dec($skips[$key], 0, '.', ',') . '%') . '">&nbsp;</span>' . $tmp_link_pre . '<img src="lib/framework/img/mark_check.gif">' . $tmp_link_pst . '</div>';
                             }
                             //end if else
                         }
                         //end if
                         //--
                     }
                     //end if else
                     //--
                 }
                 //end if
                 //--
             }
             //end foreach
             //--
         }
         //end if
         //--
         $out .= '</div></div><!-- END MIME MESSAGE HTML -->';
         //--
     }
     //end if else
     //--
     //--
     if ((string) $y_process_mode == 'data-full') {
         // output an array with message and all header info as data structure
         //--
         return array('message' => (string) $out, 'message-id' => (string) $head['message-id'], 'in-reply-to' => (string) $head['in-reply-to'], 'from' => (string) $head['from_addr'], 'to' => (string) $head['to_addr'], 'cc' => (string) $head['cc_addr'], 'date' => (string) $head['date'], 'atts_num' => (int) $reg_atts_num, 'atts_lst' => (string) $reg_atts_list, 'filepath' => (string) $the_message_eml, 'is_part' => (string) $reg_is_part);
         //--
     } elseif ((string) $y_process_mode == 'data-reply') {
         // output a special array for replies only
         //--
         $reply_text['message'] = (string) $reply_text['message'];
         // this comes from above
         $reply_text['from'] = (string) $head['from_addr'];
         $reply_text['to'] = (string) $head['to_addr'];
         $reply_text['cc'] = (string) $head['cc_addr'];
         $reply_text['date'] = (string) $head['date'];
         $reply_text['subject'] = (string) $head['subject'];
         $reply_text['message-id'] = (string) $head['message-id'];
         $reply_text['in-reply-to'] = (string) $head['in-reply-to'];
         //--
         return (array) $reply_text;
         //--
     } else {
         // 'default' or 'print' :: message as html view
         //--
         return (string) $out;
         //--
     }
     //end if
     //--
 }