/** * Generate a PDF Document on the fly from a piece of HTML code. * * Notice: this is using a secured cache folder, unique per visitor ID * * @param STRING $y_html_content :: The HTML Code * @param ENUM $y_orientation :: Page Orientation: 'normal' | 'wide' * @param STRING $y_runtime_script :: The allowed Runtime Script to allow send credentials for sub-downloads. Ex: admin.php * @param STRING $y_runtime_url :: The allowed Runtime URL ended by '/' to allow send credentials for sub-downloads. Ex: http(s)://some-server/some_path/ ; normally this should be set in config to enforce https:// and a single URL only * @param BOOLEAN $y_allow_send_credentials :: Set to TRUE to allow or set to FALSE to dissalow sending the auth credentials for sub-downloads: in the case there are embedded pictures generated by admin.php which may need authentication before to work, the credentials need to be set automatically in this case * * @returns STRING :: The PDF Document Contents * */ public static function generate($y_html_content, $y_orientation = 'normal', $y_runtime_script = '', $y_runtime_url = '', $y_allow_send_credentials = false) { //-- $pdfdata = ''; //-- $htmldoc = self::is_active(); //-- if ((string) $htmldoc != '') { //-- if ((string) $y_orientation == 'wide') { $orientation = self::tag_page_wide(); } else { $orientation = self::tag_page_normal(); } //end if else //-- $tmp_prefix_dir = 'tmp/cache/pdf/'; $protect_file = $tmp_prefix_dir . '.htaccess'; $dir = $tmp_prefix_dir . SMART_FRAMEWORK_SESSION_PREFIX . '/'; // we use different for index / admin / @ //-- $uniquifier = SmartUtils::unique_auth_client_private_key() . SMART_APP_VISITOR_COOKIE; $the_dir = $dir . Smart::safe_varname(Smart::uuid_10_seq() . '_' . Smart::uuid_10_num() . '_' . SmartHashCrypto::sha1($uniquifier)) . '/'; //-- $tmp_uuid = Smart::uuid_45($uniquifier) . Smart::uuid_36($uniquifier); $file = $the_dir . '__document_' . SmartHashCrypto::sha256('@@PDF#File::Cache@@' . $tmp_uuid) . '.html'; $logfile = $the_dir . '__headers_' . SmartHashCrypto::sha256('@@PDF#File::Cache@@' . $tmp_uuid) . '.log'; //-- if (is_dir($the_dir)) { SmartFileSystem::dir_delete($the_dir); } //end if //-- if (!is_dir($the_dir)) { SmartFileSystem::dir_recursive_create($the_dir); } // end if //-- SmartFileSystem::write_if_not_exists($protect_file, trim(SMART_FRAMEWORK_HTACCESS_FORBIDDEN) . "\n", 'yes'); //-- process the code $y_html_content = (string) self::remove_between_tags((string) $y_html_content); $y_html_content = (string) self::safe_charset((string) $y_html_content); //-- extract images $htmlparser = new SmartHtmlParser((string) $y_html_content); $arr_imgs = $htmlparser->get_tags('img'); $htmlparser = ''; unset($htmlparser); //-- $chk_duplicates_arr = array(); //-- for ($i = 0; $i < Smart::array_size($arr_imgs); $i++) { //-- $tmp_img_src = trim((string) $arr_imgs[$i]['src']); //-- if (strlen($chk_duplicates_arr[$tmp_img_src]) <= 0) { //-- $tmp_url_img_src = ''; //-- if ((string) $y_runtime_script != '' and (string) $y_runtime_url != '') { // replace relative paths if (substr($tmp_img_src, 0, @strlen($y_runtime_script)) == (string) $y_runtime_script) { $tmp_url_img_src = (string) $y_runtime_url . $tmp_img_src; $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $tmp_url_img_src . '"', (string) $y_html_content); $tmp_img_src = (string) $tmp_url_img_src; } //end if } //end if //-- $tmp_img_ext = '.' . strtolower(SmartFileSysUtils::get_file_extension_from_path($tmp_img_src)); // [OK] $tmp_img_cache = 'pdf_img_' . SmartHashCrypto::sha256('@@PDF#File::Cache::IMG@@' . '#' . $i . '@' . $tmp_img_src . '//' . $tmp_uuid); //-- $tmp_arr = array(); //-- if (substr($tmp_img_src, 0, 7) == 'http://' or substr($tmp_img_src, 0, 8) == 'https://') { //-- $tmp_img_ext = ''; // we clear the extension as we don't know yet (we will get it from headers) $tmp_img_cache = 'pdf_url_img_' . SmartHashCrypto::sha256('@@PDF#File::Cache::URL::IMG@@' . '#' . $i . '@' . $tmp_img_src . '//' . $tmp_uuid); //-- } //end if //-- if ($y_allow_send_credentials === true) { $allow_set_credentials = 'yes'; } else { $allow_set_credentials = 'no'; } //end if else //-- $tmp_arr = SmartUtils::load_url_or_file($tmp_img_src, SMART_FRAMEWORK_NETSOCKET_TIMEOUT, 'GET', '', '', '', $allow_set_credentials); // [OK] :: allow set credentials //-- $tmp_img_ext = '.noextension'; $tmp_where_we_guess = ''; //-- $guess_arr = array(); //-- $guess_arr = SmartUtils::guess_image_extension_by_url_head($tmp_arr['headers']); $tmp_img_ext = (string) $guess_arr['extension']; $tmp_where_we_guess = (string) $guess_arr['where-was-detected']; $guess_arr = array(); if ((string) $tmp_img_ext == '') { $tmp_img_ext = SmartUtils::guess_image_extension_by_first_bytes(substr($tmp_arr['content'], 0, 256)); if ((string) $tmp_img_ext != '') { $tmp_where_we_guess = ' First Bytes ...'; } //end if } //end if //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { // if debug, append information to log SmartFileSystem::write($logfile, '####################' . "\n" . '#################### [FILE # ' . $i . ' = \'' . $tmp_img_src . '\']' . "\n\n" . '==== [MODE] :: ' . $tmp_arr['mode'] . "\n" . '==== [LOG] :: ' . "\n" . $tmp_arr['log'] . "\n" . '==== [HEADERS] ::' . "\n" . $tmp_arr['headers'] . "\n" . '########' . "\n" . '==== [GUESS EXTENSION] :: ' . $tmp_where_we_guess . "\n\n" . '###################' . "\n\n\n\n", 'a'); } //end if //-- if ((string) $tmp_arr['result'] == '1' and (string) $tmp_arr['code'] == '200') { //-- SmartFileSystem::write($the_dir . $tmp_img_cache . $tmp_img_ext, $tmp_arr['content']); //-- if empty, it may be a file if ((string) $tmp_img_ext == '' or (string) $tmp_img_ext == '.png' or (string) $tmp_img_ext == '.gif' or (string) $tmp_img_ext == '.jpg') { $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $tmp_img_cache . $tmp_img_ext . '"', (string) $y_html_content); } else { // we want to avoid html code to be loaded as image by mistakes of http browser class or servers $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $y_runtime_url . 'lib/framework/img/sign_warn.png"', (string) $y_html_content); } //end if else //-- } else { //-- $y_html_content = (string) @str_replace('src="' . $tmp_img_src . '"', 'src="' . $y_runtime_url . 'lib/framework/img/sign_error.png"', (string) $y_html_content); //-- } //end if //-- } //end if //-- $chk_duplicates_arr[$tmp_img_src] = 'processed'; //-- } //end for //-- $chk_duplicates_arr = array(); unset($chk_duplicates_arr); $arr_imgs = array(); unset($arr_imgs); //-- SmartFileSystem::write($file, $orientation . "\n" . $y_html_content); //-- if (is_file($file)) { //-- ob_start(); //-- @passthru($htmldoc . ' ' . self::pdf_options($file)); //-- $pdfdata = ob_get_clean(); //-- } else { //-- Smart::log_warning('ERROR: PDF Generator Failed to find the PDF Document: ' . $file . "\n" . $y_html_content); //-- } //end if else //-- cleanup if ((string) SMART_FRAMEWORK_DEBUG_MODE != 'yes') { // if not debug, cleanup the dir if (is_dir($the_dir)) { SmartFileSystem::dir_delete($the_dir); } //end if } //end if //-- } else { //-- Smart::log_notice('NOTICE: PDF Generator is INACTIVE ...'); //-- } //end if //-- return (string) $pdfdata; //-- }
/** * Send Email Mime Message from custom MailBox to a destination * * @param ARRAY $y_server_settings arr = [ server_name, server_port, server_sslmode, server_auth_user, server_auth_pass, send_from_addr, send_from_name, smtp_mxdomain ] * @param ENUM $y_mode 'send' = do send | 'send-return' = do send + return | 'return' = return mime formated mail * @param STRING $to To: * @param STRING $cc Cc: | empty * @param STRING $subj Subject: * @param STRING $message Body/Message: * @param TRUE/FALSE $is_html * Format: Html or Text/Plain * @param ARRAY $attachments * $attachments = array('file1.txt'=>'This is the file 1 content', ...); * @param ENUM $charset * charset * @param ENUM $priority * 1=High ; 3=Normal ; 5=Low * @param STRING $inreplyto '' | the ID of message that is replying to * @return ARRAY OPERATION RESULT, ERROR, MIME MESSAGE */ public static function send_extended_email($y_server_settings, $y_mode, $to, $cc, $subj, $message, $is_html, $attachments, $charset, $priority, $inreplyto, $bcc = '', $replytoaddr = '') { //-- SMTP Hello $server_helo = trim($y_server_settings['smtp_mxdomain']); //-- SMTP connection vars $server_name = trim($y_server_settings['server_name']); $server_port = trim($y_server_settings['server_port']); $server_sslmode = trim($y_server_settings['server_sslmode']); $server_user = trim($y_server_settings['server_auth_user']); $server_pass = trim($y_server_settings['server_auth_pass']); //-- SEND FROM $send_from_addr = trim($y_server_settings['send_from_addr']); $send_from_name = trim($y_server_settings['send_from_name']); //-- //-- mail send class init $mail = new SmartMailerSend(); $mail->usealways_b64 = true; //-- if ((string) $server_name == '@mail') { //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { SmartFrameworkRegistry::setDebugMsg('mail', 'SEND', 'Send eMail Method Selected: [MAIL]'); } //end if //-- mail method $mail->method = 'mail'; //-- } elseif (strlen($server_name) > 0) { //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { SmartFrameworkRegistry::setDebugMsg('mail', 'SEND', 'Send eMail Method Selected: [SMTP]'); } //end if //-- smtp server method $mail->method = 'smtp'; $mail->smtp_timeout = '30'; //-- $mail->smtp_helo = $server_helo; $mail->smtp_server = $server_name; $mail->smtp_port = $server_port; $mail->smtp_ssl = $server_sslmode; //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { $mail->debuglevel = 1; // default is 1 } else { $mail->debuglevel = 0; // no debug } //end if else //-- if ((string) $server_user == '' or (string) $server_pass == '') { $mail->smtp_login = false; } else { $mail->smtp_login = true; $mail->smtp_user = $server_user; $mail->smtp_password = $server_pass; } //end if //-- } else { //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { SmartFrameworkRegistry::setDebugMsg('mail', 'SEND', 'Send eMail Method Selected: [NONE] !!!'); } //end if //-- $mail->method = 'skip'; //-- } //end if else //-- //-- charset if ((string) $charset == '') { $charset = 'UTF-8'; // default } //end if //-- $mail->charset = (string) $charset; //-- //-- if ((string) $mail->charset != 'UTF-8') { // in this case (ISO-88591 / ISO-8859-2) we deaccent the things for maximum compatibility $send_from_name = SmartUnicode::deaccent_str($send_from_name); $subj = SmartUnicode::deaccent_str($subj); $message = SmartUnicode::deaccent_str($message); } //end if //-- //-- $tmp_explode_arr = (array) explode('@', (string) $send_from_addr); $tmp_name = trim($tmp_explode_arr[0]); // not used $tmp_domain = trim($tmp_explode_arr[1]); // used for message ID //-- $tmp_my_uid = getmyuid(); $tmp_my_gid = getmygid(); //-- //-- Extra Mail Headers $mail->headers = ''; //-- Errors Reporting Header $mail->headers .= 'Errors-To: ' . $send_from_addr . "\r\n"; //-- In-Reply-To Header if ((string) $inreplyto != '') { $mail->headers .= 'In-Reply-To: ' . $inreplyto . "\r\n"; } //end if else //-- Reply-To Header if ((string) $replytoaddr != '') { $mail->headers .= 'Reply-To: ' . $replytoaddr . "\r\n"; } //end if //-- antiSPAM Header $mail->headers .= 'X-AntiAbuse: This header was added to track abuse, please include it with any abuse report' . "\r\n"; $mail->headers .= 'X-AntiAbuse: Primary Hostname - ' . $server_helo . "\r\n"; $mail->headers .= 'X-AntiAbuse: Original Domain - ' . $server_helo . "\r\n"; $mail->headers .= 'X-AntiAbuse: Originator/Caller UID/GID - [48880 48885] / [' . $tmp_my_uid . ' ' . $tmp_my_gid . ']' . "\r\n"; $mail->headers .= 'X-AntiAbuse: Sender Address Domain - ' . $tmp_domain . "\r\n"; //-- //-- $mail->priority = $priority; // high=1 | low=5 | normal=3 //-- //-- from $mail->from_return = $send_from_addr; $mail->from = $send_from_addr; $mail->namefrom = $send_from_name; //-- //-- subject $mail->subject = $subj; //-- //-- if message is html, include CID imgs as attachments if ((string) $y_mode != 'return' and $is_html) { //-- init $arr_links = array(); //-- embedd all images $htmlparser = new SmartHtmlParser($message); $htmlparser->get_clean_html(); // to be tested ... $arr_links = $htmlparser->get_tags('img'); $htmlparser = ''; unset($htmlparser); //-- $chk_duplicates_arr = array(); $uniq_id = 0; //-- for ($i = 0; $i < Smart::array_size($arr_links); $i++) { //-- $tmp_original_img_link = trim($arr_links[$i][src]); // trim any possible spaces //-- reverse the & back to & (generated from JavaScript) ... $tmp_imglink = str_replace('&', '&', (string) $tmp_original_img_link); //-- $tmp_cid = 'img_' . sha1('SmartFramework eMail-Utils // CID Embedd // ' . '@' . $tmp_imglink . '#'); // this should not vary by $i or others because if duplicate images are detected only the first is attached //-- if (strlen($chk_duplicates_arr[$tmp_cid]) <= 0) { // avoid browse twice the same image //-- $tmp_original_lnk = (string) $tmp_imglink; $tmp_eval_link = (string) $tmp_imglink; $tmp_allow_credentials = 'no'; if (substr($tmp_original_lnk, 0, 10) == 'admin.php?') { $tmp_original_lnk = (string) SmartUtils::get_server_current_url() . $tmp_imglink; $tmp_allow_credentials = 'yes'; // in the case we have embedded pictures generated by admin.php who always need authentication to work, we have to send credentials too $tmp_eval_link = ''; // we clear to re-eval } elseif (SmartUnicode::sub_str($tmp_original_lnk, 0, SmartUnicode::str_len(SmartUtils::get_server_current_url() . 'admin.php?')) == SmartUtils::get_server_current_url() . 'admin.php?' and (substr($tmp_original_lnk, 0, 7) == 'http://' or substr($tmp_original_lnk, 0, 8) == 'https://')) { $tmp_allow_credentials = 'yes'; // in the case we have embedded pictures generated by admin.php who always need authentication to work, we have to send credentials too $tmp_eval_link = ''; // we clear to re-eval } elseif (substr($tmp_original_lnk, 0, 10) == 'index.php?' or substr($tmp_original_lnk, 0, 1) == '?') { $tmp_original_lnk = (string) SmartUtils::get_server_current_url() . $tmp_imglink; $tmp_eval_link = ''; // we clear to re-eval } elseif (SmartUnicode::sub_str($tmp_original_lnk, 0, SmartUnicode::str_len(SmartUtils::get_server_current_url() . 'index.php?')) == SmartUtils::get_server_current_url() . 'index.php?' and (substr($tmp_original_lnk, 0, 7) == 'http://' or substr($tmp_original_lnk, 0, 8) == 'https://')) { $tmp_eval_link = ''; // we clear to re-eval } elseif (SmartUnicode::sub_str($tmp_original_lnk, 0, SmartUnicode::str_len(SmartUtils::get_server_current_url() . '?')) == SmartUtils::get_server_current_url() . '?' and (substr($tmp_original_lnk, 0, 7) == 'http://' or substr($tmp_original_lnk, 0, 8) == 'https://')) { $tmp_eval_link = ''; // we clear to re-eval } //end if //-- $tmp_browse_arr = array(); $tmp_browse_arr = SmartUtils::load_url_or_file($tmp_original_lnk, SMART_FRAMEWORK_NETSOCKET_TIMEOUT, 'GET', '', '', '', $tmp_allow_credentials); // [OK] //Smart::log_notice(print_r($tmp_browse_arr,1)); //-- $guess_arr = array(); $guess_arr = SmartUtils::guess_image_extension_by_url_head($tmp_browse_arr['headers']); $tmp_img_ext = (string) $guess_arr['extension']; $tmp_where_we_guess = (string) $guess_arr['where-was-detected']; //Smart::log_notice('Guess Ext by URL Head: '.$tmp_browse_arr['headers']."\n".'### '.print_r($guess_arr,1)."\n".'#'); if ((string) $tmp_img_ext == '') { $tmp_img_ext = SmartUtils::guess_image_extension_by_first_bytes(substr($tmp_browse_arr['content'], 0, 256)); if ((string) $tmp_img_ext != '') { $tmp_where_we_guess = ' First Bytes ...'; } //end if } //end if //Smart::log_notice('Guess Ext by First Bytes: '.$tmp_img_ext."\n".'#'); if ((string) $tmp_eval_link == '') { $tmp_eval_link = 'file' . $tmp_img_ext; } //end if //-- $tmp_fcontent = ''; if ((string) $tmp_browse_arr['result'] == '1' and (string) $tmp_browse_arr['code'] == '200') { if ((string) $tmp_img_ext == '' or (string) $tmp_img_ext == '.png' or (string) $tmp_img_ext == '.gif' or (string) $tmp_img_ext == '.jpg') { $tmp_fcontent = (string) $tmp_browse_arr['content']; } //end if } //end if else //-- if (strlen($tmp_fcontent) > 0) { //-- $tmp_arr_fmime = array(); $tmp_arr_fmime = SmartFileSysUtils::mime_eval($tmp_eval_link); //-- $tmp_fmime = (string) $tmp_arr_fmime[0]; if ((string) $tmp_fmime == '' or (string) $tmp_fmime == 'application/octet-stream') { $tmp_fmime = 'image'; // in the case of CIDS we already pre-validated the images } //end if $tmp_fname = 'cid_' . $uniq_id . '__' . $tmp_cid . $tmp_img_ext; //-- $mail->add_attachment($tmp_fcontent, $tmp_fname, $tmp_fmime, 'inline', $tmp_cid . $tmp_img_ext); // attachment $message = str_replace('src="' . $tmp_original_img_link . '"', 'src="cid:' . $tmp_cid . $tmp_img_ext . '"', $message); //-- $uniq_id += 1; //-- } //end if //-- $chk_duplicates_arr[$tmp_cid] = 'embedd'; //-- } //end if //-- } //end for //-- clean $chk_duplicates_arr = array(); $uniq_id = 0; $tmp_original_img_link = ''; $tmp_imglink = ''; $tmp_cid = ''; $tmp_browse_arr = array(); $tmp_fcontent = ''; $tmp_arr_fmime = array(); $tmp_fmime = ''; $tmp_fname = ''; //-- } //end if //-- //-- message body $mail->is_html = $is_html; // false | true $mail->body = $message; //-- $message = ''; unset($message); //-- //-- attachments if (is_array($attachments)) { if (Smart::array_size($attachments) > 0) { while (list($key, $val) = each($attachments)) { //-- $tmp_arr_fmime = array(); $tmp_arr_fmime = SmartFileSysUtils::mime_eval($key); //-- $mail->add_attachment($val, $key, (string) $tmp_arr_fmime[0], 'attachment', '', 'yes'); // force as real attachments //-- } //end while } //end if } //end if //-- //-- switch ((string) $y_mode) { case 'return': //-- $mail->to = '[::!::]'; $mail->cc = ''; //-- only return mime formated message $mail->send('no'); return array('result' => 1, 'error' => '', 'message' => $mail->mime_message); //-- break; case 'send-return': case 'send': default: //-- $out = 0; //-- $arr_to = array(); if (!is_array($to)) { $arr_to[] = (string) $to; $tmp_send_to = (string) $to; } else { $arr_to = (array) $to; if (Smart::array_size($arr_to) > 1) { $tmp_send_to = '[::@::]'; // multi message } else { $tmp_send_to = (string) $arr_to[0]; } //end if else } //end if else //-- $tmp_send_log = ''; $tmp_send_log .= '-----------------------------------------------------------------------' . "\n"; $tmp_send_log .= 'Smart / eMail Send Log :: ' . $send_from_addr . ' [' . $send_from_name . ']' . "\n"; $tmp_send_log .= $server_sslmode . '://' . $server_name . ':' . $server_port . ' # ' . $server_user . ' :: ' . $server_helo . "\n"; $tmp_send_log .= '-----------------------------------------------------------------------' . "\n"; //-- $counter_sent = 0; for ($i = 0; $i < Smart::array_size($arr_to); $i++) { //-- $arr_to[$i] = trim($arr_to[$i]); //-- if (strlen($arr_to[$i]) > 0) { //-- $mail->to = (string) $arr_to[$i]; //-- $mail->cc = $cc; // can be string or array //-- $mail->bcc = (string) $bcc; //-- $tmp_send_log .= '#' . ($i + 1) . '. To: \'' . $arr_to[$i] . '\' :: ' . date('Y-m-d H:i:s O'); //-- real send if ((string) $mail->method == 'mail' or (string) $mail->method == 'smtp') { $err = $mail->send('yes'); if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { SmartFrameworkRegistry::setDebugMsg('mail', 'SEND', 'Send eMail Log #' . ($i + 1) . ': ' . $mail->log); } //end if } else { $err = 'WARNING: SMTP Server or Mail Method IS NOT SET in CONFIG. Send eMail - Operation ABORTED !'; } //end if else //-- if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { SmartFrameworkRegistry::setDebugMsg('mail', 'SEND', '========== SEND TO: ' . $arr_to[$i] . ' ==========' . "\n" . 'ERRORS: ' . $err . "\n" . '==========' . "\n" . $mail->log . "\n" . '========== # =========='); } //end if //-- if (strlen($err) > 0) { $tmp_send_log .= ' :: ERROR:' . "\n" . $arr_to[$i] . "\n" . $err . "\n"; } else { $counter_sent += 1; $tmp_send_log .= ' :: OK' . "\n"; } //end if else //-- if ($i > 10000) { break; // hard limit } //end if //-- } //end if //-- } //end for //-- if ($counter_sent > 0) { $out = 1; } //end if //-- $tmp_send_log .= '-----------------------------------------------------------------------' . "\n\n"; if ((string) SMART_FRAMEWORK_DEBUG_MODE == 'yes') { SmartFrameworkRegistry::setDebugMsg('mail', 'SEND', 'Send eMail Operations Log: ' . $tmp_send_log); } //end if //-- if ((string) $y_mode == 'send-return') { $mail->to = $tmp_send_to; if (is_array($cc)) { $mail->cc = (string) implode(', ', $cc); } elseif ((string) $cc != '') { $mail->cc = (string) $cc; } //end if else $mail->add_attachment($tmp_send_log, 'smart-email-send.log', 'text/plain', 'inline'); $mail->send('no'); return array('result' => $out, 'error' => $err, 'log' => $tmp_send_log, 'message' => $mail->mime_message); } else { return array('result' => $out, 'error' => $err, 'log' => $tmp_send_log, 'message' => ''); // skip returning the message } //end if else //-- } //end switch //-- }