public function external_hook($hook) { switch ($hook) { case 'view': $file_id = isset($_REQUEST['i']) ? (int) $_REQUEST['i'] : false; $hash = isset($_REQUEST['hash']) ? trim($_REQUEST['hash']) : false; if ($file_id && $hash) { $correct_hash = $this->link_public($file_id, true); if ($correct_hash == $hash) { // all good to print a receipt for this payment. $file_data = $this->get_file($file_id, false); if ($file_data && $file_data['file_id'] == $file_id) { if (isset($_POST['save_file_comments'])) { if (isset($_POST['file_approve']) && isset($_POST['file_approve_go']) && isset($_POST['file_approve_name']) && strlen($_POST['file_approve_name']) > 0) { update_insert('file_id', $file_id, 'file', array('approved_time' => time(), 'approved_by' => $_POST['file_approve_name'])); // send email, same 'updated' email as before. $this->send_file_changed_notice($file_id, false, true); //redirect_browser($this->link_public($file_id)); $_REQUEST['new_comment_text'] = _l('File was approved at %s by %s', print_date(time(), true), htmlspecialchars($_POST['file_approve_name'])); } if (isset($_POST['pointers'])) { update_insert('file_id', $file_id, 'file', array('pointers' => $_POST['pointers'])); } $this->save_file_comments($file_id); redirect_browser($this->link_public($file_id)); } module_template::init_template('file_approval_view', '<h2>File Details</h2> File Name: <strong>{FILE_NAME}</strong> <br/> Download: <strong><a href="{FILE_DOWNLOAD_URL}">Click Here</a></strong> <br/> Status: <strong>{STATUS}</strong> <br/> Customer: <strong>{CUSTOMER_NAME}</strong> <br/> {if:JOB_NAME}Job: <strong>{JOB_NAME}</strong> <br/>{endif:JOB_NAME} {if:FILE_APPROVAL_PENDING} <h2>File Approval Pending</h2> <p>If you would like to approve this file please complete the form below:</p> <p>Your Name: <input type="text" name="file_approve_name"> </p> <p><input type="checkbox" name="file_approve_go" value="yes"> Yes, I approve this file. </p> <p><input type="submit" name="file_approve" value="Approve File" class="submit_button save_button"></p> {endif:FILE_APPROVAL_PENDING} {if:FILE_APPROVED} <h2>File Has Been Approved</h2> <p>Thank you, the file was approved by <strong>{APPROVED_BY}</strong> on <strong>{APPROVED_TIME}</strong>.</p> {endif:FILE_APPROVED} <h2>File Comments</h2> <p>Please feel free to add comments to this file using the form below.</p> {FILE_COMMENTS} {if:FILE_PREVIEW} <h2>File Preview</h2> <div style="overflow:scroll;">{FILE_PREVIEW}</div> {endif:FILE_PREVIEW} ', 'Used when displaying the file to a customer for approval.', 'code'); $template = module_template::get_template_by_key('file_approval_view'); // generate the html for the task output $job_data = $file_data['job_id'] ? module_job::get_replace_fields($file_data['job_id']) : array(); if (class_exists('module_quote', false)) { $quote_data = $file_data['quote_id'] ? module_quote::get_replace_fields($file_data['quote_id']) : array(); } $customer_data = $file_data['customer_id'] ? module_customer::get_replace_fields($file_data['customer_id']) : array(); $file_data['file_preview'] = module_file::generate_preview($file_id, $file_data['file_name'], $file_data); $file_data['FILE_DOWNLOAD_URL'] = module_file::link_public_view($file_id); if (isset($file_data['approved_time'])) { switch ($file_data['approved_time']) { case -1: $file_data['FILE_APPROVAL_PENDING'] = 1; break; case 0: break; default: $file_data['FILE_APPROVED'] = 1; $file_data['APPROVED_TIME'] = print_date($file_data['approved_time'], true); } } if (class_exists('module_extra', false) && module_extra::is_plugin_enabled()) { $all_extra_fields = module_extra::get_defaults('file'); foreach ($all_extra_fields as $e) { $file_data[$e['key']] = _l('N/A'); } // and find the ones with values: $extras = module_extra::get_extras(array('owner_table' => 'file', 'owner_id' => $file_id)); foreach ($extras as $e) { $file_data[$e['extra_key']] = $e['extra']; } } ob_start(); ?> <div id="file_notes"> <div style="border-top:1px dashed #CCCCCC; padding:3px; margin:3px 0;"> <textarea name="new_comment_text" style="width:100%;" class="no_permissions"></textarea> <div style="text-align: right;"> <input type="submit" name="butt_save_note" id="butt_save_note" value="<?php echo _l('Add Comment'); ?> " class="submit_button no_permissions"> </div> </div> <?php foreach (module_file::get_file_comments($file_id) as $item) { $note_text = forum_text($item['comment']); if (preg_match_all('/#(\\d+)/', $note_text, $matches)) { // foreach ($matches[1] as $digit) { $note_text = preg_replace('/#' . $digit . '([^\\d]*)/', '<span node_id=' . $digit . ' class="pointer-ids pointer-id-' . $digit . '">#' . $digit . '</span>$1', $note_text); } } ?> <div style="border-top:1px dashed #CCCCCC; padding:3px; margin:3px 0;"> <?php echo $note_text; ?> <div style="font-size:10px; text-align:right; color:#CCCCCC;">From <?php echo $item['create_user_id'] ? module_user::link_open($item['create_user_id'], true) : _l('Customer'); ?> on <?php echo print_date($item['date_created'], true); ?> </div> </div> <?php } ?> </div> <?php $file_data['file_comments'] = ob_get_clean(); $template->assign_values($file_data); $template->assign_values($customer_data); $template->assign_values($job_data); if (class_exists('module_quote', false)) { $quote_data['quote_approved_by'] = $quote_data['approved_by']; $quote_data['quote_date_approved'] = $quote_data['date_approved']; unset($quote_data['approved_by']); unset($quote_data['date_approved']); $template->assign_values($quote_data); } $template->page_title = $file_data['file_name']; $template->content = '<form action="" method="post"><input type="hidden" name="save_file_comments" value="1">' . $template->content . '</form>'; echo $template->render('pretty_html'); } } } break; case 'download_bucket': @ob_end_clean(); $file_id = isset($_REQUEST['i']) ? (int) $_REQUEST['i'] : false; $hash = isset($_REQUEST['hash']) ? trim($_REQUEST['hash']) : false; if ($file_id && $hash) { $correct_hash = $this->link_public_download_bucket($file_id, true); if ($correct_hash == $hash) { // all good to print a receipt for this payment. $file_data = $this->get_file($file_id, false); @ignore_user_abort(true); $search = array(); $search['bucket_parent_file_id'] = $file_id; $files = module_file::get_files($search); //Create ZIP $zip = new ZipArchive(); $zipName = "bucket-" . $file_id . "-" . md5($file_id . _UCM_SECRET) . ".zip"; if ($zip->open(_FILE_UPLOAD_PATH . $zipName, ZIPARCHIVE::CREATE) !== TRUE) { echo 'Failed to create bucket zip file'; exit; } foreach ($files as $file) { if (is_file($file['file_path'])) { $zip->addFromString($file['file_name'], file_get_contents($file['file_path'])); } } $zip->close(); //Set headers header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: public"); header("Content-Description: File Transfer"); header("Content-type: application/octet-stream"); //header("Content-Disposition: attachment; filename='" . $zipName . "'"); header("Content-Disposition: attachment; filename=\"" . preg_replace("#[^a-zA-Z0-9]+#", "-", $file_data['file_name']) . ".zip\";"); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . filesize(_FILE_UPLOAD_PATH . $zipName)); @clearstatcache(); //Make sure the file size isn't cached $size = @readfile(_FILE_UPLOAD_PATH . $zipName); if (!$size) { echo file_get_contents(_FILE_UPLOAD_PATH . $zipName); } @unlink(_FILE_UPLOAD_PATH . $zipName); } } exit; break; case 'download': @ob_end_clean(); $file_id = isset($_REQUEST['i']) ? (int) $_REQUEST['i'] : false; $hash = isset($_REQUEST['hash']) ? trim($_REQUEST['hash']) : false; if ($file_id && $hash) { $correct_hash = $this->link_public_view($file_id, true); if ($correct_hash == $hash) { // all good to print a receipt for this payment. $file_data = $this->get_file($file_id, false); if (isset($file_data['file_url']) && strlen($file_data['file_url'])) { redirect_browser($file_data['file_url']); } else { if (is_file($file_data['file_path'])) { header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private", false); header("Content-type: " . dtbaker_mime_type($file_data['file_name'], $file_data['file_path'])); if (!isset($_REQUEST['embed'])) { header("Content-Disposition: attachment; filename=\"" . $file_data['file_name'] . "\";"); header("Content-Transfer-Encoding: binary"); } header("Content-Length: " . filesize($file_data['file_path'])); //readfile($file_data['file_path']); $size = @readfile($file_data['file_path']); if (!$size) { echo file_get_contents($file_data['file_path']); } } else { echo 'Not found'; } } } } exit; break; } }
/** * Used only when admin/user replies via web interface * Or when a new ticket/reply is submitted via public interface * Or when an autoreply is sent * */ public static function send_reply($ticket_id, $message, $from_user_id, $to_user_id, $reply_type = 'admin', $internal_from = '', $other_options = array()) { // we also check if this message contains anything, or anything above the "reply line" // this is a hack to stop the autoreply loop that seems to happen when sending an email as yourself from your envato profile. // stip out the text before our "--reply above this line-- bit. // copied code from ticket_admin_edit.php /*$reply__ine_default = '----- (Please reply above this line) -----'; // incase they change it $reply__ine = module_config::s('ticket_reply_line',$reply__ine_default); $text = preg_replace("#<br[^>]*>#",'',$message); // convert to single text. $text = preg_replace('#\s+#imsU',' ',$text); if( preg_match('#^\s*'.preg_quote($reply__ine,'#').'.*#ims',$text) || preg_match('#^\s*'.preg_quote($reply__ine_default,'#').'.*#ims',$text) ){ // no content. don't send email //mail('*****@*****.**','ticket reply '.$ticket_id,'sending reply for text:\''.$text."' \n\n\n Original:\n".$message); return false; }*/ // $message is in text format, need to nl2br it before printing. $ticket_number = self::ticket_number($ticket_id); $ticket_details = self::get_ticket($ticket_id); $to_user_a = module_user::get_user($to_user_id, false); $from_user_a = module_user::get_user($from_user_id, false); // we have to replace some special text within these messages. this is just a hack to support text in my autoreply. $replace = array('name' => $to_user_a['name'], 'ticket_url' => module_ticket::link_public($ticket_id), 'ticket_url_cancel' => module_ticket::link_public_status($ticket_id, 7), 'ticket_url_resolved' => module_ticket::link_public_status($ticket_id, _TICKET_STATUS_RESOLVED_ID), 'ticket_url_inprogress' => module_ticket::link_public_status($ticket_id, 5), 'faq_product_id' => $ticket_details['faq_product_id']); foreach ($replace as $key => $val) { $message = str_replace('{' . strtoupper($key) . '}', $val, $message); } // the from details need to match the ticket account details. if ($ticket_details['ticket_account_id']) { $ticket_account = self::get_ticket_account($ticket_details['ticket_account_id']); } else { $ticket_account = false; } if ($ticket_account && $ticket_account['email']) { // want the user to reply to our ticketing system. $reply_to_address = $ticket_account['email']; $reply_to_name = $ticket_account['name']; } else { // reply to creator of the email. $reply_to_address = $from_user_a['email']; $reply_to_name = $from_user_a['name']; } $htmlmessage = ''; if (self::is_text_html($message)) { $htmlmessage = $message; $message = strip_tags($message); } $ticket_message_data = array('ticket_id' => $ticket_id, 'content' => $message, 'htmlcontent' => $htmlmessage, 'message_time' => time(), 'from_user_id' => $from_user_id, 'to_user_id' => $to_user_id, 'message_type_id' => $reply_type == 'admin' ? _TICKET_MESSAGE_TYPE_ADMIN : _TICKET_MESSAGE_TYPE_CREATOR, 'private_message' => isset($other_options['private_message']) && $other_options['private_message'] ? $other_options['private_message'] : 0); if ($internal_from == 'autoreply') { $ticket_message_data['message_type_id'] = _TICKET_MESSAGE_TYPE_AUTOREPLY; } if (self::can_edit_tickets()) { // we look for the extra cc/bcc headers. if (module_config::c('ticket_allow_cc_bcc', 1)) { $headers = array(); // look for cc staff options here. if (isset($_POST['ticket_cc_staff']) && is_array($_POST['ticket_cc_staff'])) { $admins_rel = self::get_ticket_staff_rel(); foreach ($admins_rel as $staff_id => $staff_name) { if (isset($_POST['ticket_cc_staff'][$staff_id])) { $staff_user = module_user::get_user($staff_id); if ($staff_user && isset($staff_user['email']) && strlen($staff_user['email'])) { // found a staff member to cc! if (!isset($headers['cc_emails'])) { $headers['cc_emails'] = array(); } $headers['cc_emails'][] = array('address' => $staff_user['email']); } } } } if (isset($_POST['ticket_cc']) && strlen($_POST['ticket_cc'])) { $bits = explode(',', $_POST['ticket_cc']); foreach ($bits as $b) { $b = trim($b); if (strlen($b)) { if (!isset($headers['cc_emails'])) { $headers['cc_emails'] = array(); } $headers['cc_emails'][] = array('address' => $b); } } } if (isset($_POST['ticket_bcc']) && strlen($_POST['ticket_bcc'])) { $bits = explode(',', $_POST['ticket_bcc']); foreach ($bits as $b) { $b = trim($b); if (strlen($b)) { if (!isset($headers['bcc_emails'])) { $headers['bcc_emails'] = array(); } $headers['bcc_emails'][] = array('address' => $b); } } } if (count($headers)) { $ticket_message_data['cache'] = serialize($headers); } } } $ticket_message_id = update_insert('ticket_message_id', 'new', 'ticket_message', $ticket_message_data); if (!$ticket_message_id) { return false; } // handle any attachemnts. // are there any attachments? if ($ticket_message_id && isset($_FILES['attachment']) && isset($_FILES['attachment']['tmp_name']) && is_array($_FILES['attachment']['tmp_name'])) { foreach ($_FILES['attachment']['tmp_name'] as $key => $val) { if (is_uploaded_file($val)) { // save attachments against ticket! $mime = dtbaker_mime_type($_FILES['attachment']['name'][$key], $val); $attachment_id = update_insert('ticket_message_attachment_id', 'new', 'ticket_message_attachment', array('ticket_id' => $ticket_id, 'ticket_message_id' => $ticket_message_id, 'file_name' => $_FILES['attachment']['name'][$key], 'content_type' => $mime)); //echo getcwd();exit; //ini_set('display_errors',true); if (!move_uploaded_file($val, 'includes/plugin_ticket/attachments/' . $attachment_id . '')) { //echo 'error uploading file';exit; } } } } if ($internal_from != 'autoreply') { // stops them all having the same timestamp on a big import. update_insert('ticket_id', $ticket_id, 'ticket', array('last_message_timestamp' => time())); /*}else{ // we are sending an auto reply, flag this in the special cache field. // hacky! update_insert('ticket_message_id',$ticket_message_id,'ticket_message',array( 'cache'=>'autoreply', ));*/ } //$reply_line = module_config::s('ticket_reply_line','----- (Please reply above this line) -----'); $s = self::get_statuses(); if (isset($other_options['private_message']) && $other_options['private_message']) { // private message, dont send an email to the customer. if (!self::is_text_html($message)) { $message = nl2br(htmlspecialchars($message)); // because message is in text format, before we send admin notification do this. } module_ticket::send_admin_alert($ticket_id, strlen($htmlmessage) ? $htmlmessage : $message, true); } else { if ($to_user_id == $ticket_details['user_id']) { // WE ARE emailing the "User" from support. // so the support is emailing a response back to the customer. module_ticket::send_customer_alert($ticket_id, strlen($htmlmessage) ? $htmlmessage : $message, $ticket_message_id); } else { if (!self::is_text_html($message)) { $message = nl2br(htmlspecialchars($message)); // because message is in text format, before we send admin notification do this. } module_ticket::send_admin_alert($ticket_id, strlen($htmlmessage) ? $htmlmessage : $message); } if ($reply_type == 'end_user' && (!$ticket_details['message_count'] || module_config::c('ticket_autoreply_every_message', 0))) { // this is the first message! // send an email back to the user confirming this submissions via the web interface. self::send_autoreply($ticket_id, $message); } } return $ticket_message_id; }