public function action_wp_ajax_supportflow_json()
 {
     $response = array('api-action' => !empty($_REQUEST['api-action']) ? sanitize_key($_REQUEST['api-action']) : '', 'status' => 'error', 'message' => '', 'html' => '');
     switch ($response['api-action']) {
         case 'get-customers':
             check_ajax_referer('get_customers', 'get_customers_nonce');
             if (current_user_can('sf_get_customers')) {
                 $search_for = sanitize_text_field(isset($_REQUEST['customers']) ? $_REQUEST['customers'] : '');
                 $customer_matches = SupportFlow()->get_customers(array('search' => $search_for));
             } else {
                 $customer_matches = new WP_Error('sf_access_denied', __('Access denied.', 'supportflow'));
             }
             if (is_wp_error($customer_matches)) {
                 $response['message'] = $customer_matches->get_error_message();
             } else {
                 $response['query'] = $search_for;
                 $response['status'] = "ok";
                 $response['customers'] = $customer_matches;
             }
             break;
         default:
             $response['message'] = __("There's no API method registered under that action.", 'supportflow');
             break;
     }
     $response = apply_filters('supportflow_json_api_response', $response);
     @header('Content-Type: application/json; charset=' . get_option('blog_charset'));
     echo json_encode($response);
     die;
 }
 /**
  * Add predefined options under Supportflow menu
  */
 public function action_admin_menu_predefined_replies()
 {
     $post_type = SupportFlow()->post_type;
     $predefinded_replies_type = SupportFlow()->predefinded_replies_type;
     add_submenu_page("edit.php?post_type={$post_type}", 'All predefined replies', 'All predefined replies', 'manage_options', "edit.php?post_type={$predefinded_replies_type}");
     add_submenu_page("edit.php?post_type={$post_type}", 'New predefined reply', 'New predefined reply', 'manage_options', "post-new.php?post_type={$predefinded_replies_type}");
 }
 public function get_attachment_id($attachment_secret)
 {
     $post_statuses = SupportFlow()->post_statuses;
     $posts = get_posts(array('post_type' => 'attachment', 'post_status' => 'inherit', 'meta_query' => array(array('key' => 'sf_attachment_secret', 'value' => $attachment_secret))));
     if (isset($posts[0])) {
         return $posts[0]->ID;
     } else {
         return 0;
     }
 }
示例#4
0
 /**
  * Setup globals that require some of the other classes to be loaded
  */
 protected function setup_late_globals()
 {
     /*
      * Gmail might block access if a client checks more than every 10 minutes.
      * https://support.google.com/mail/answer/14257?p=client_login&rd=1
      */
     $this->cron_interval = SupportFlow()->extend->email_accounts->has_gmail_account() ? 10 * MINUTE_IN_SECONDS : 5 * MINUTE_IN_SECONDS;
     $this->cron_interval = apply_filters('supportflow_cron_interval', $this->cron_interval);
 }
    public function action_template_redirect()
    {
        global $current_user;
        wp_enqueue_script($this->script_slug, plugins_url('js/supportflow-user-widget.js', dirname(__FILE__)), array('jquery'), mt_rand());
        $ajaxurl = add_query_arg('action', SupportFlow()->extend->jsonapi->action, admin_url('admin-ajax.php'));
        $widget_title = __('Support', 'supportflow');
        $start_ticket_text = __('Start ticket', 'supportflow');
        $starting_ticket_text = __('Starting ticket...', 'supportflow');
        $send_reply_text = __('Send reply', 'supportflow');
        $sending_reply_text = __('Sending reply...', 'supportflow');
        wp_localize_script($this->script_slug, 'SupportFlowUserWidgetVars', array('ajaxurl' => $ajaxurl, 'widget_title' => $widget_title, 'start_ticket_text' => $start_ticket_text, 'starting_ticket_text' => $starting_ticket_text, 'send_reply_text' => $send_reply_text, 'sending_reply_text' => $sending_reply_text));
        wp_enqueue_style($this->script_slug, plugins_url('css/widget.css', dirname(__FILE__)), array(), mt_rand());
        ?>
		<html>
		<head>
			<title><?php 
        _e('Support', 'supportflow');
        ?>
</title>

			<?php 
        wp_head();
        ?>
		</head>
		<body>

		<div id="supportflow-widget">
			<button id="supportflow-back"><?php 
        _e('All Tickets', 'supportflow');
        ?>
</button>
			<h1 id="widget-title"><?php 
        echo $widget_title;
        ?>
</h1>

			<div id="supportflow-newticket-box">
				<button id="supportflow-newticket"><?php 
        _e('Start a new ticket', 'supportflow');
        ?>
</button>
				<form id="supportflow-newticket-form">
					<input type="text" id="new-ticket-subject" name="new-ticket-subject" class="ticket-subject" placeholder="<?php 
        esc_attr_e('What can we help with?', 'supportflow');
        ?>
" autocomplete="off" />
					<textarea id="new-ticket-message" name="new-ticket-message" class="ticket-message" cols="25" rows="6" placeholder="<?php 
        esc_attr_e('Tell us a bit more...', 'supportflow');
        ?>
" autocomplete="off"></textarea>
					<input id="new-ticket-submit" type="submit" name="new-ticket-submit" class="submit-button" value="<?php 
        echo esc_attr($start_ticket_text);
        ?>
" />
				</form>
			</div>

			<div id="supportflow-all-tickets">
				<?php 
        echo $this->render_all_tickets_html();
        ?>
			</div>

			<div id="supportflow-single-ticket">
				<div id="supportflow-ticket-body">
				</div>
				<form id="supportflow-existing-ticket-form">
					<textarea id="existing-ticket-message" name="existing-ticket-message" class="ticket-message" cols="25" rows="6" autocomplete="off"></textarea>
					<input id="existing-ticket-submit" type="submit" name="existing-ticket-submit" class="submit-button" value="<?php 
        echo esc_attr($send_reply_text);
        ?>
" />
					<input id="existing-ticket-id" name="ticket-id" type="hidden" />
				</form>
			</div>
		</div>

		</body>
		</html>
		<?php 
        exit;
    }
 public function is_user_allowed_post($user_id, $post_id)
 {
     $user_permissions = $this->get_user_permissions_data($user_id);
     $post_email_account = get_post_meta($post_id, 'email_account', true);
     $post_tags = wp_get_post_terms($post_id, SupportFlow()->tags_tax);
     if (in_array($post_email_account, $user_permissions['email_accounts'])) {
         return true;
     }
     foreach ($post_tags as $post_tag) {
         $post_tag_slug = $post_tag->slug;
         if (in_array($post_tag_slug, $user_permissions['tags'])) {
             return true;
         }
     }
     return false;
 }
 public function action_init_handle_form_submission()
 {
     if (!isset($_POST['action'], $_POST['_wpnonce']) || !'sf_create_ticket' == $_POST['action'] || !wp_verify_nonce($_POST['_wpnonce'], '_sf_create_ticket')) {
         return;
     }
     if (empty($_POST['fullname'])) {
         $this->messages[] = __('The name field is required.', 'supportflow');
     }
     if (empty($_POST['email'])) {
         $this->messages[] = __('The email field is required.', 'supportflow');
     } elseif (!is_email($_POST['email'])) {
         $this->messages[] = __('Please enter a valid e-mail address.', 'supportflow');
     }
     if (empty($_POST['subject'])) {
         $this->messages[] = __('The subject field is required.', 'supportflow');
     }
     if (empty($_POST['message'])) {
         $this->messages[] = __('You must enter a message.', 'supportflow');
     }
     if (!empty($this->messages)) {
         return;
     }
     // Load required file
     require_once SupportFlow()->plugin_dir . 'classes/class-supportflow-admin.php';
     $ticket_id = SupportFlow()->create_ticket(array('subject' => $_POST['subject'], 'message' => $_POST['message'], 'reply_author' => $_POST['fullname'], 'reply_author_email' => $_POST['email'], 'customer_email' => array($_POST['email'])));
     if (is_wp_error($ticket_id)) {
         $this->messages[] = __('There is an unknown error while submitting the form. Please try again later.', 'supportflow');
         return;
     }
     $this->messages[] = __('Form submitted successfully', 'supportflow');
 }
 function action_sf_my_tickets()
 {
     $statuses = SupportFlow()->post_statuses;
     $status_slugs = array();
     foreach ($statuses as $status => $status_data) {
         if (true == $status_data['show_tickets']) {
             $status_slugs[] = $status;
         }
     }
     $table = new SupportFlow_Table();
     $user_id = get_current_user_id();
     foreach ($status_slugs as $status_slug) {
         $args = array('post_type' => SupportFlow()->post_type, 'post_parent' => 0, 'posts_per_page' => 10, 'post_status' => $status_slug, 'author' => $user_id);
         $wp_query = new WP_Query($args);
         $tickets = $wp_query->posts;
         $no_items = '<a href="post-new.php?post_type=' . SupportFlow()->post_type . '">' . __('<b>Click here</b>') . '</a>';
         $no_items = sprintf(__('No matching ticket exists. %s to create new.', 'supportflow'), $no_items);
         $table->set_no_items($no_items);
         $table->set_columns(array('title' => __('Subject', 'supportflow'), 'modified' => __('Last modified', 'supportflow'), 'datetime' => __('Created', 'supportflow')));
         $data = array();
         foreach ($tickets as $ticket) {
             $post_date = strtotime($ticket->post_date);
             $post_modified = strtotime($ticket->post_modified);
             $title = '<b>' . esc_html($ticket->post_title) . '</b>';
             $title = "<a href='post.php?post=" . $ticket->ID . "&action=edit'>" . $title . "</a>";
             $data[] = array('title' => $title, 'modified' => sprintf(__('%s ago', 'supportflow'), human_time_diff(time(), $post_modified)), 'datetime' => sprintf(__('%s ago', 'supportflow'), human_time_diff(time(), $post_date)));
         }
         $table->set_data($data);
         echo '<div class="container">';
         echo "<h3 class='toggle-link'>" . $statuses[$status_slug]['label'] . "</h3>";
         echo "<div class='toggle-content'>";
         $table->display();
         echo "</div>";
         echo '</div>';
     }
 }
 /**
  * AJAX request to change user E-Mail notification settings
  */
 public function action_wp_ajax_set_email_notfication()
 {
     check_ajax_referer('set_email_notfication', '_set_email_notfication_nonce');
     if (!isset($_POST['privilege_type']) || !isset($_POST['privilege_id']) || !isset($_POST['allowed']) || !in_array($_POST['privilege_type'], array('email_accounts', 'tags'))) {
         exit;
     }
     $privilege_type = $_POST['privilege_type'];
     $privilege_id = $_POST['privilege_id'];
     $allowed = 'true' == $_POST['allowed'] ? true : false;
     echo SupportFlow()->extend->email_notifications->set_notfication_settings($privilege_type, $privilege_id, $allowed);
     exit;
 }
 /**
  * Add a page to display log items
  *
  * Disabled by default to avoid cluttering the menu with something that is rarely used
  */
 public function add_admin_menu_items()
 {
     if (apply_filters('supportflow_show_log', false)) {
         add_submenu_page('edit.php?post_type=' . SupportFlow()->post_type, __('Log', 'supportflow'), __('Log', 'supportflow'), 'manage_options', 'log', array($this, 'markup_log_page'));
     }
 }
 public function get_quoted_text($ticket)
 {
     // Insert last second reply as quoted text
     $replies = SupportFlow()->get_ticket_replies($ticket->ID, array('numberposts' => 2));
     if (empty($replies[1])) {
         return '';
     } else {
         $quoted_reply = $replies[1];
         $reply_author = get_post_meta($quoted_reply->ID, 'reply_author', true);
         if (empty($reply_author)) {
             $reply_author = get_post_meta($ticket_reply->ID, 'reply_author_email', true);
         }
         $time_stamp = $ticket->post_date_gmt;
         $heading = sprintf("On %s GMT, %s wrote:", $time_stamp, $reply_author);
         $content = SupportFlow()->sanitize_ticket_reply(stripslashes($quoted_reply->post_content));
         $content = "> {$content}";
         $content = str_replace("\n", "\n> ", $content);
         return "{$heading}\n{$content}";
     }
 }
示例#12
0
 /**
  * Get the special capability given a string
  */
 public function get_cap($cap)
 {
     return SupportFlow()->extend->permissions->get_cap($cap);
 }
 /**
  * Given an email object, maybe create a new ticket
  */
 public function process_email($imap_connection, $email, $i, $to, $email_account_id)
 {
     require_once ABSPATH . 'wp-admin/includes/admin.php';
     $new_attachment_ids = array();
     $k = 0;
     if (isset($email->structure->parts)) {
         foreach ($email->structure->parts as $email_part) {
             // We should at least be dealing with something that resembles an email object at this point
             if (!isset($email_part->disposition, $email_part->subtype, $email_part->dparameters[0]->value)) {
                 continue;
             }
             if ('ATTACHMENT' == $email_part->disposition) {
                 // We need to add 2 to our array key each time to get the correct email part
                 //@todo this needs more testing with different emails, should be smarter about which parts
                 $raw_attachment_data = imap_fetchbody($imap_connection, $i, $k + 2);
                 // The raw data from imap is base64 encoded, but php-imap has us covered!
                 $attachment_data = imap_base64($raw_attachment_data);
                 $temp_file = get_temp_dir() . time() . '_supportflow_temp.tmp';
                 touch($temp_file);
                 $temp_handle = fopen($temp_file, 'w+');
                 fwrite($temp_handle, $attachment_data);
                 fclose($temp_handle);
                 $file_array = array('tmp_name' => $temp_file, 'name' => $email_part->dparameters[0]->value);
                 $upload_result = media_handle_sideload($file_array, null);
                 if (is_wp_error($upload_result)) {
                     WP_CLI::warning($upload_result->get_error_message());
                 } else {
                     SupportFlow()->extend->attachments->secure_attachment_file($upload_result);
                     $new_attachment_ids[] = $upload_result;
                 }
             }
             $k++;
         }
     }
     if (!empty($email->headers->subject)) {
         $subject = imap_utf8($email->headers->subject);
     } else {
         $subject = sprintf(__('New ticket from %s', 'supportflow'), $email->headers->fromaddress);
     }
     $reply_author = isset($email->headers->from[0]->personal) ? $email->headers->from[0]->personal : '';
     $reply_author_email = $email->headers->from[0]->mailbox . '@' . $email->headers->from[0]->host;
     // Parse out the reply body
     if (function_exists('What_The_Email')) {
         $message = What_The_Email()->get_message($email->body);
     } else {
         $message = $email->body;
     }
     // Check if this email should be blocked
     if (function_exists('What_The_Email')) {
         $check_strings = array('subject' => $subject, 'sender' => $reply_author_email, 'message' => $message);
         foreach ($check_strings as $key => $value) {
             if (What_The_Email()->is_robot($key, $value)) {
                 SupportFlow()->extend->logger->log('email_retrieve', __METHOD__, __('Skipping e-mail because sender is a robot.', 'supportflow'), compact('email'));
                 return true;
             }
         }
     }
     // Check to see if this message was in response to an existing ticket
     $ticket_id = false;
     if (preg_match('/#(\\d+):/', $subject, $matches)) {
         $ticket_id = $matches[1];
         $ticket = get_post($ticket_id);
         // Make sure the ticket ID is a SupportFlow ticket with a valid status.
         if ($ticket->post_type != SupportFlow()->post_type || !array_key_exists($ticket->post_status, SupportFlow()->post_statuses)) {
             $ticket_id = false;
         }
     }
     // Back-compat with old-style secrets.
     if (!$ticket_id && preg_match('#\\[([a-zA-Z0-9]{8})\\]$#', $subject, $matches)) {
         $ticket_id = SupportFlow()->get_ticket_from_secret($matches[1]);
     }
     // Add anyone else that was in the 'to' or 'cc' fields as customers
     $customers = array();
     $fields = array('to', 'cc');
     foreach ($fields as $field) {
         if (!empty($email->headers->{$field})) {
             foreach ($email->headers->{$field} as $recipient) {
                 $email_address = $recipient->mailbox . '@' . $recipient->host;
                 if (is_email($email_address) && $email_address != SupportFlow()->extend->emails->from_address && strcasecmp($email_address, $to) != 0) {
                     $customers[] = $email_address;
                 }
             }
         }
     }
     $customers[] = $reply_author_email;
     $customers = apply_filters('supportflow_new_email_customers', $customers, $email, $ticket_id, $email_account_id);
     $message = SupportFlow()->sanitize_ticket_reply($message);
     if ($ticket_id) {
         $reply_args = array('reply_author' => $reply_author, 'reply_author_email' => $reply_author_email);
         SupportFlow()->update_ticket_customers($ticket_id, $customers, true);
         SupportFlow()->add_ticket_reply($ticket_id, $message, $reply_args);
     } else {
         // If this wasn't in reply to an existing message, create a new ticket
         $new_ticket_args = array('subject' => $subject, 'reply_author' => $reply_author, 'reply_author_email' => $reply_author_email, 'message' => $message, 'customer_email' => $customers, 'email_account' => $email_account_id);
         $ticket_id = SupportFlow()->create_ticket($new_ticket_args);
     }
     $all_replies = SupportFlow()->get_ticket_replies($ticket_id);
     $new_reply = $all_replies[count($all_replies) - 1];
     foreach ($new_attachment_ids as $new_attachment_id) {
         // Save the attachment ID as post meta of reply
         add_post_meta($new_reply->ID, 'sf_attachments', $new_attachment_id);
         SupportFlow()->extend->attachments->insert_attachment_secret_key($new_attachment_id);
         // It doesn't do anything special other than making sure file is not shown as unattached in media page
         wp_update_post(array('ID' => $new_attachment_id, 'post_parent' => $ticket_id));
     }
     // Store the original email ID so we don't accidentally dupe it
     $email_id = trim($email->headers->message_id, '<>');
     if (is_object($new_reply)) {
         update_post_meta($new_reply->ID, self::email_id_key, $email_id);
     }
     SupportFlow()->extend->logger->log('email_retrieve', __METHOD__, sprintf(__('Successfully imported e-mail from %s.', 'supportflow'), $reply_author_email));
     return true;
 }
 /**
  * Get user id of all the users that will receive e-mail notifications for a ticket reply
  *
  * @param type $ticket_id
  *
  * @return type array
  */
 public function get_notified_user($ticket_id)
 {
     $tags = wp_get_post_terms($ticket_id, SupportFlow()->tags_tax, array('fields' => 'slugs'));
     $email_account = get_post_meta($ticket_id, 'email_account', true);
     $email_notifications_override = get_post_meta($ticket_id, 'email_notifications_override', true);
     if (!is_array($email_notifications_override)) {
         $email_notifications_override = array();
     }
     $notifications_settings = $this->get_notifications_settings(null, true);
     $allowed_users = array();
     foreach ($notifications_settings as $notifications_setting) {
         if (in_array($notifications_setting['user_id'], $allowed_users)) {
             continue;
         }
         if ('tags' == $notifications_setting['privilege_type']) {
             $user_notified = in_array($notifications_setting['privilege_id'], $tags);
         } elseif ('email_accounts' == $notifications_setting['privilege_type']) {
             $user_notified = $email_account == $notifications_setting['privilege_id'];
         }
         if ($user_notified) {
             $allowed_users[] = $notifications_setting['user_id'];
         }
     }
     foreach ($email_notifications_override as $user_id => $status) {
         if ('disable' == $status && in_array($user_id, $allowed_users)) {
             unset($allowed_users[array_search($user_id, $allowed_users)]);
         }
         if ('enable' == $status && !in_array($user_id, $allowed_users)) {
             $allowed_users[] = $user_id;
         }
     }
     return $allowed_users;
 }
 /**
  * Add a new E-Mail account to database
  */
 function add_email_account($imap_host, $imap_port, $imap_ssl, $smtp_host, $smtp_port, $smtp_ssl, $username, $password, $test_login = true)
 {
     global $phpmailer;
     $email_accounts =& $this->email_accounts;
     $imap_host = sanitize_text_field($imap_host);
     $imap_port = intval($imap_port);
     $imap_ssl = (bool) $imap_ssl;
     $smtp_host = sanitize_text_field($smtp_host);
     $smtp_port = intval($smtp_port);
     $smtp_ssl = (bool) $smtp_ssl;
     $username = sanitize_text_field($username);
     $password = sanitize_text_field($password);
     if ($this->email_account_exists($imap_host, $smtp_host, $username)) {
         SupportFlow()->extend->logger->log('email_accounts', __METHOD__, __('Account already exists.', 'supportflow'), compact('imap_host', 'imap_port', 'imap_ssl', 'smtp_host', 'smtp_port', 'smtp_ssl', 'username'));
         return self::ACCOUNT_EXISTS;
     }
     if ($test_login) {
         imap_timeout(IMAP_OPENTIMEOUT, apply_filters('supportflow_imap_open_timeout', 5));
         $ssl = $imap_ssl ? '/ssl' : '';
         $ssl = apply_filters('supportflow_imap_ssl', $ssl, $imap_host);
         $mailbox = '{' . $imap_host . ':' . $imap_port . $ssl . '}';
         if ($imap_stream = imap_open($mailbox, $username, $password, 0, 0)) {
             SupportFlow()->extend->logger->log('email_accounts', __METHOD__, __('Successfully opened IMAP connection.', 'supportflow'), compact('imap_host', 'imap_port', 'imap_ssl', 'smtp_host', 'smtp_port', 'smtp_ssl', 'username', 'mailbox'));
             imap_close($imap_stream);
         } else {
             $imap_errors = imap_errors();
             $error = $imap_errors[0];
             SupportFlow()->extend->logger->log('email_accounts', __METHOD__, __('Failed to open IMAP connection.', 'supportflow'), compact('imap_host', 'imap_port', 'imap_ssl', 'smtp_host', 'smtp_port', 'smtp_ssl', 'username', 'mailbox', 'imap_errors'));
             if ((string) strpos($error, 'Host not found') != '') {
                 return self::IMAP_HOST_NOT_FOUND;
             } elseif ((string) strpos($error, 'Timed out') != '') {
                 return self::IMAP_TIME_OUT;
             } elseif ((string) strpos($error, 'Invalid credentials') != '') {
                 return self::IMAP_INVALID_CREDENTIALS;
             } else {
                 return self::IMAP_CONNECTION_FAILED;
             }
         }
         // Initialize PHPMailer
         wp_mail('', '', '');
         // Set PHPMailer SMTP settings
         $phpmailer->IsSMTP();
         $phpmailer->Host = $smtp_host;
         $phpmailer->Port = $smtp_port;
         $phpmailer->SMTPSecure = $smtp_ssl ? 'ssl' : '';
         $phpmailer->SMTPAutoTLS = $smtp_ssl;
         $phpmailer->Username = $username;
         $phpmailer->Password = $password;
         $phpmailer->SMTPAuth = true;
         // $phpmail raise fatal error on SMTP connect failure
         try {
             $smtp_authentication = $phpmailer->smtpConnect();
         } catch (Exception $e) {
             $smtp_authentication = false;
             SupportFlow()->extend->logger->log('email_accounts', __METHOD__, sprintf(__('PHPMailer exception: %s.', 'supportflow'), $e->getMessage()), compact('smtp_host', 'smtp_port', 'smtp_ssl', 'username'));
         }
         SupportFlow()->extend->logger->log('email_accounts', __METHOD__, $smtp_authentication ? __('Successfully authenticated with SMTP server.', 'supportflow') : __('Failed to authenticate with SMTP server.', 'supportflow'), compact('imap_host', 'imap_port', 'imap_ssl', 'smtp_host', 'smtp_port', 'smtp_ssl', 'username', 'mailbox'));
         if (!$smtp_authentication) {
             return self::SMTP_AUTHENTICATION_FAILED;
         }
     }
     $email_accounts[] = array('imap_host' => $imap_host, 'imap_port' => $imap_port, 'imap_ssl' => $imap_ssl, 'smtp_host' => $smtp_host, 'smtp_port' => $smtp_port, 'smtp_ssl' => $smtp_ssl, 'username' => $username, 'password' => $password);
     update_option('sf_email_accounts', $email_accounts);
     return self::SUCCESS;
 }
 /**
  * When a ticket is saved or updated, make sure we save the customer
  * and new reply data
  */
 public function action_save_post($ticket_id)
 {
     $email_account_id = get_post_meta($ticket_id, 'email_account', true);
     $email_account = SupportFlow()->extend->email_accounts->get_email_account($email_account_id);
     $ticket_lock = null == $email_account && '' != $email_account;
     if (SupportFlow()->post_type != get_post_type($ticket_id)) {
         return;
     }
     if (isset($_POST['customers'])) {
         $customers = array_map('sanitize_email', explode(',', $_POST['customers']));
         SupportFlow()->update_ticket_customers($ticket_id, $customers);
     }
     if (isset($_POST['post_email_account']) && is_numeric($_POST['post_email_account']) && '' == $email_account_id) {
         $email_account = (int) $_POST['post_email_account'];
         update_post_meta($ticket_id, 'email_account', $email_account);
     }
     if (isset($_POST['post_email_notifications_override']) && in_array($_POST['post_email_notifications_override'], array('default', 'enable', 'disable'))) {
         $email_notifications_override = get_post_meta($ticket_id, 'email_notifications_override', true);
         $email_notifications_override[get_current_user_id()] = $_POST['post_email_notifications_override'];
         update_post_meta($ticket_id, 'email_notifications_override', $email_notifications_override);
     }
     if (isset($_POST['reply']) && !empty($_POST['reply']) && !$ticket_lock) {
         $reply = $_POST['reply'];
         if (isset($_POST['insert-signature']) && 'on' == $_POST['insert-signature']) {
             $agent_signature = get_user_meta(get_current_user_id(), 'sf_user_signature', true);
             if (!empty($agent_signature)) {
                 $reply .= "\n\n-----\n{$agent_signature}";
             }
         }
         $reply = SupportFlow()->sanitize_ticket_reply($reply);
         $visibility = !empty($_POST['mark-private']) ? 'private' : 'public';
         if (!empty($_POST['reply-attachments'])) {
             $attachements = explode(',', trim($_POST['reply-attachments'], ','));
             // Remove same attachment added more than once
             $attachements = array_unique($attachements);
             // Remove non-int attachment ID's from array
             $attachements = array_filter($attachements, function ($val) {
                 return (string) (int) $val === (string) $val;
             });
             $attachment_ids = array_map('intval', $attachements);
         } else {
             $attachment_ids = '';
         }
         $cc = !empty($_POST['cc']) ? SupportFlow()->extract_email_ids($_POST['cc']) : '';
         $bcc = !empty($_POST['bcc']) ? SupportFlow()->extract_email_ids($_POST['bcc']) : '';
         $reply_args = array('post_status' => $visibility, 'attachment_ids' => $attachment_ids, 'cc' => $cc, 'bcc' => $bcc);
         SupportFlow()->add_ticket_reply($ticket_id, $reply, $reply_args);
     }
 }
 /**
  * Generate a link that shows matching tickets in all ticket page
  *
  * @param string $link_tag    Slug of tag
  * @param string $post_status Post statuses that should be shown in all tickets page
  * @param string $link_value  Value of hyperlink that should be shown to user
  *
  * @return string A hyperlink
  */
 function get_post_link_by_tag($link_tag = null, $post_status = null, $link_value = null)
 {
     $link = '<a href="edit.php?%s%s%s">%s</a>';
     $post_type = 'post_type=' . SupportFlow()->post_type;
     $post_status = is_null($post_status) ? '' : "&post_status={$post_status}";
     $date = is_null($link_tag) ? '' : '&' . SupportFlow()->tags_tax . "={$link_tag}";
     $value = is_null($link_value) ? '' : "{$link_value}";
     return sprintf($link, $post_type, $post_status, $date, $value);
 }