/**
 * Change a ticket status to open.
 *
 * @since  3.0.2
 *
 * @param  integer $ticket_id ID of the ticket to re-open
 *
 * @return integer|boolean            ID of the post meta if exists, true on success or false on failure
 */
function wpas_reopen_ticket($ticket_id)
{
    if ('ticket' !== get_post_type($ticket_id)) {
        return false;
    }
    if (!current_user_can('edit_ticket') && !wpas_can_submit_ticket($ticket_id)) {
        return false;
    }
    $update = update_post_meta(intval($ticket_id), '_wpas_status', 'open');
    /* Log the action */
    wpas_log($ticket_id, __('The ticket was re-opened.', 'awesome-support'));
    /**
     * wpas_after_reopen_ticket hook
     *
     * @since  3.0.2
     */
    do_action('wpas_after_reopen_ticket', intval($ticket_id), $update);
    return $update;
}
Example #2
0
 /**
  * Save ticket custom fields.
  *
  * This function will save all custom fields associated
  * to the ticket post type. Be it core custom fields
  * or user added custom fields.
  * 
  * @param  (int) $post_id Current post ID
  * @since  3.0.0
  */
 public function save_ticket($post_id)
 {
     /* We should already being avoiding Ajax, but let's make sure */
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE || wp_is_post_revision($post_id)) {
         return;
     }
     if (defined('DOING_AJAX') && DOING_AJAX) {
         return;
     }
     /* Now we check the nonce */
     if (!isset($_POST[Awesome_Support_Admin::$nonce_name]) || !wp_verify_nonce($_POST[Awesome_Support_Admin::$nonce_name], Awesome_Support_Admin::$nonce_action)) {
         return;
     }
     /* Does the current user has permission? */
     if (!current_user_can('edit_ticket', $post_id)) {
         return;
     }
     global $current_user, $wpas_cf;
     /**
      * Store possible logs
      */
     $log = array();
     /**
      * If no ticket status is found we are in the situation where
      * the agent is creating a ticket on behalf of the user. There are
      * a couple of things that we need to do then.
      */
     if ('' === ($original_status = get_post_meta($post_id, '_wpas_status', true))) {
         /**
          * First of all, set the ticket as open. This is very important.
          */
         add_post_meta($post_id, '_wpas_status', 'open', true);
         /**
          * Send the confirmation e-mail to the user.
          *
          * @since  3.1.5
          */
         wpas_email_notify($post_id, 'submission_confirmation');
     }
     /* Save the possible ticket reply */
     if (isset($_POST['wpas_reply']) && isset($_POST['wpas_reply_ticket']) && '' != $_POST['wpas_reply']) {
         /* Check for the nonce */
         if (wp_verify_nonce($_POST['wpas_reply_ticket'], 'reply_ticket')) {
             $user_id = $current_user->ID;
             $content = wp_kses_post($_POST['wpas_reply']);
             $data = apply_filters('wpas_post_reply_admin_args', array('post_content' => $content, 'post_status' => 'read', 'post_type' => 'ticket_reply', 'post_author' => $user_id, 'post_parent' => $post_id, 'ping_status' => 'closed', 'comment_status' => 'closed'));
             /**
              * Remove the save_post hook now as we're going to trigger
              * a new one by inserting the reply (and logging the history later).
              */
             remove_action('save_post_ticket', array($this, 'save_ticket'));
             /**
              * Fires right before a ticket reply is submitted
              *
              * @since 3.2.6
              *
              * @param int   $post_id Ticket ID
              * @param array $data    Data to be inserted as the reply
              */
             do_action('wpas_post_reply_admin_before', $post_id, $data);
             /* Insert the reply in DB */
             $reply = wpas_add_reply($data, $post_id);
             /**
              * Fires right after a ticket reply is submitted
              *
              * @since 3.2.6
              *
              * @param int      $post_id Ticket ID
              * @param array    $data    Data to be inserted as the reply
              * @param bool|int Reply    ID on success, false on failure
              */
             do_action('wpas_post_reply_admin_after', $post_id, $data, $reply);
             /* In case the insertion failed... */
             if (is_wp_error($reply)) {
                 /* Set the redirection */
                 $_SESSION['wpas_redirect'] = add_query_arg(array('wpas-message' => 'wpas_reply_error'), get_permalink($post_id));
             } else {
                 /* E-Mail the client */
                 $new_reply = new WPAS_Email_Notification($post_id, array('reply_id' => $reply, 'action' => 'reply_agent'));
                 /* The agent wants to close the ticket */
                 if (isset($_POST['wpas_do']) && 'reply_close' == $_POST['wpas_do']) {
                     /* Confirm the post type and close */
                     if ('ticket' == get_post_type($post_id)) {
                         /**
                          * wpas_ticket_before_close_by_agent hook
                          */
                         do_action('wpas_ticket_before_close_by_agent', $post_id);
                         /* Close */
                         $closed = wpas_close_ticket($post_id);
                         /* E-Mail the client */
                         new WPAS_Email_Notification($post_id, array('action' => 'closed'));
                         /**
                          * wpas_ticket_closed_by_agent hook
                          */
                         do_action('wpas_ticket_closed_by_agent', $post_id);
                     }
                 }
             }
         }
     }
     /* Now we can save the custom fields */
     $wpas_cf->save_custom_fields($post_id, $_POST);
     /* Log the action */
     if (!empty($log)) {
         wpas_log($post_id, $log);
     }
     /* If this was a ticket update, we need to know where to go now... */
     if ('' !== $original_status) {
         /* Go back to the tickets list */
         if (isset($_POST['wpas_back_to_list']) && true === boolval($_POST['wpas_back_to_list']) || isset($_POST['where_after']) && 'back_to_list' === $_POST['where_after']) {
             $_SESSION['wpas_redirect'] = add_query_arg(array('post_type' => 'ticket'), admin_url('edit.php'));
         }
     }
 }
 /**
  * Save the custom fields.
  *
  * The following method will get all options,
  * check if they have  a submissed value, prefix and save it to the DB.
  * 
  * @param  (integer) $post_id Post ID
  * @since 3.0.0
  */
 public function save($post_id = '')
 {
     /* Need the parent object */
     global $wpas_cf;
     /**
      * Clear! We can go ahead now...
      */
     $options = $wpas_cf->get_custom_fields();
     /**
      * Save the possible messages in this array
      */
     $messages = array();
     /**
      * Save all notifications to send in this array for a later expedition
      */
     $notify = array();
     /**
      * If some of the fields are to be logged in the ticket history, we save it here
      */
     $log = array();
     /* Go through all our options */
     foreach ($options as $option) {
         $option_name = 'wpas_' . sanitize_text_field($option['name']);
         $option_args = $option['args'];
         /* Prepare current value */
         if (isset($_POST[$option_name])) {
             $value = function_exists($option_args['sanitize']) ? $option_args['sanitize']($_POST[$option_name]) : sanitize_text_field($_POST[$option_name]);
         }
         /* Use a custom saving function if the save_callback is defined */
         if (false !== $option_args['save_callback']) {
             if (is_null($option_args['save_callback'])) {
                 continue;
             }
             if (function_exists($option_args['save_callback'])) {
                 call_user_func($option_args['save_callback'], $value, $post_id);
                 continue;
             }
         }
         /* Process the agent (re)attribution differently */
         if ('assignee' === $option['name']) {
             /* Don't od anything if the agent didn't change */
             if ($_POST[$option_name] == get_post_meta($post_id, '_wpas_assignee', true)) {
                 continue;
             }
             wpas_assign_ticket($post_id, $_POST[$option_name], $option_args['log']);
             continue;
         }
         /* We handle different option types differently */
         if ('taxonomy' != $option_args['callback']) {
             /* Form the meta key */
             $key = "_{$option_name}";
             /* Get current option */
             $current = get_post_meta($post_id, $key, true);
             /**
              * First case scenario
              *
              * The option exists in DB but there is no value
              * for it in the POST. This is often the case
              * for checkboxes.
              *
              * Action: Delete option
              */
             if ('' != $current && !isset($_POST[$option_name])) {
                 /* Delete the post meta */
                 delete_post_meta($post_id, $key, $current);
                 /* Log the action */
                 if (true === $option_args['log']) {
                     $log[] = array('action' => 'deleted', 'label' => wpas_get_field_title($option), 'value' => $current, 'field_id' => $option['name']);
                 }
             } elseif ('' != $current && isset($_POST[$option_name])) {
                 /* If an actual value is set, we udpate the post meta */
                 if ('' != $value && $current != $value) {
                     update_post_meta($post_id, $key, $value, $current);
                     /* Log the action */
                     if (true === $option_args['log']) {
                         $log[] = array('action' => 'updated', 'label' => wpas_get_field_title($option), 'value' => $value, 'field_id' => $option['name']);
                     }
                 } elseif ('' == $value) {
                     delete_post_meta($post_id, $key, $current);
                     /* Log the action */
                     if (true === $option_args['log']) {
                         $log[] = array('action' => 'deleted', 'label' => wpas_get_field_title($option), 'value' => $current, 'field_id' => $option['name']);
                     }
                 }
             } elseif ('' == $current && isset($_POST[$option_name])) {
                 /* Let's not add an empty value */
                 if ('' != $value) {
                     add_post_meta($post_id, $key, $value, true);
                     /* Log the action */
                     if (true === $option_args['log']) {
                         $log[] = array('action' => 'added', 'label' => wpas_get_field_title($option), 'value' => $value, 'field_id' => $option['name']);
                     }
                 }
             } else {
                 // Do nothing
             }
         } elseif ('taxonomy' == $option_args['callback']) {
             /* Check if this taxonomy has to be handled as a select */
             if (true === $option_args['taxo_std']) {
                 continue;
             }
             /* Clean the taxonomy name */
             $taxonomy = substr($option_name, 5);
             /* If no value is submitted we delete the term relationship */
             if (!isset($_POST[$option_name]) || empty($_POST[$option_name])) {
                 $terms = wp_get_post_terms($post_id, $taxonomy);
                 if (!empty($terms)) {
                     wp_delete_object_term_relationships($post_id, $option_name);
                     /* Log the action */
                     if (true === $option_args['log']) {
                         $log[] = array('action' => 'deleted', 'label' => wpas_get_field_title($option), 'value' => $current, 'field_id' => $option['name']);
                     }
                 }
                 continue;
             }
             /* Get all the terms for this ticket / taxo (we should have only one term) */
             $terms = get_the_terms($post_id, $taxonomy);
             /**
              * As the taxonomy is handled like a select, we should have only one value. At least
              * that's what we want. Hence, we loop through the possible multiple terms (which
              * shouldn't happen) and only keep the last one.
              */
             if (is_array($terms)) {
                 foreach ($terms as $term) {
                     $the_term = $term->term_id;
                 }
             } else {
                 $the_term = '';
             }
             /* Finally we save the new terms if changed */
             if ($the_term !== (int) $value) {
                 $term = get_term_by('id', (int) $value, $taxonomy);
                 if (false === $term) {
                     continue;
                 }
                 /**
                  * Apply the get_term filters.
                  * 
                  * @var object
                  */
                 $term = get_term($term, $taxonomy);
                 wp_set_object_terms($post_id, (int) $value, $taxonomy, false);
                 /* Log the action */
                 if (true === $option_args['log']) {
                     $log[] = array('action' => 'updated', 'label' => wpas_get_field_title($option), 'value' => $term->name, 'field_id' => $option['name']);
                 }
             }
         }
         /**
          * Fired right after the option is updated
          */
         do_action("wpas_cf_updated_{$option_name}");
         /**
          * If a message is associated to this option, we add it now
          */
         if (isset($option_args['message'])) {
             $messages[] = $option_args['message'];
         }
         /**
          * If an e-mail notification has to be sent we store it temporarily
          */
         if (isset($option_args['notification'])) {
             $notify[] = $option_args['notification'];
         }
     }
     /**
      * Log the changes
      */
     if (!empty($log)) {
         wpas_log($post_id, $log);
     }
 }
 /**
  * Save all custom fields given in $data to the database.
  *
  * @since 3.2.0
  *
  * @param int   $post_id   ID of the post being saved
  * @param array $data      Array of data that might contain custom fields values.
  * @param bool  $allow_log Whether or not to allow logging actions. If this is set to false and the custom field is
  *                         set to true, $log has higher priority. I tis used to prevent logging on ticket creation.
  *
  * @return array Array of custom field / value saved to the database
  */
 public function save_custom_fields($post_id, $data = array(), $allow_log = true)
 {
     /* We store all the data to log in here */
     $log = array();
     /* Store all fields saved to DB and the value saved */
     $saved = array();
     $fields = $this->get_custom_fields();
     /**
      * wpas_save_custom_fields_before hook
      *
      * @since  3.0.0
      */
     do_action('wpas_save_custom_fields_before', $post_id);
     foreach ($fields as $field_id => $field) {
         /**
          * All name attributes are prefixed with wpas_
          * so we need to add it to get the real field ID.
          */
         $field_form_id = "wpas_{$field_id}";
         /* Process core fields differently. */
         if (true === $field['args']['core']) {
             if (isset($data[$field_form_id])) {
                 $this->save_core_field($post_id, $field, $data[$field_form_id]);
             }
             continue;
         }
         /**
          * Ignore fields in "no edit" mode.
          *
          * If we're on the admin and the custom field is set as
          * "no edit" (by restricting the capability), then the field
          * won't be passed in the $_POST, which as a result would have
          * the field deleted.
          *
          * If the no edit mode is enabled for the current field, we simply ignore it.
          */
         if (is_admin() && !current_user_can($field['args']['capability'])) {
             continue;
         }
         /**
          * Get the custom field object.
          */
         $custom_field = new WPAS_Custom_Field($field_id, $field);
         if (isset($data[$field_form_id])) {
             $value = $custom_field->get_sanitized_value($data[$field_form_id]);
             $result = $custom_field->update_value($value, $post_id);
         } else {
             /**
              * This is actually important as passing an empty value
              * for custom fields that aren't set in the form allows
              * for deleting values that aren't used from the database.
              * An unchecked checkbox for instance will not be set
              * in the form even though the value has to be deleted.
              */
             $value = '';
             $result = $custom_field->update_value($value, $post_id);
         }
         if (1 === $result || 2 === $result) {
             $saved[$field['name']] = $value;
         }
         if (true === $field['args']['log'] && true === $allow_log) {
             /**
              * If the custom field is a taxonomy we need to convert the term ID into its name.
              *
              * By checking if $result is different from 0 we make sure that the term actually exists.
              * If the term didn't exist the save function would have seen it and returned 0.
              */
             if ('taxonomy' === $field['args']['field_type'] && 0 !== $result) {
                 $term = get_term((int) $value, $field['name']);
                 $value = $term->name;
             }
             /**
              * If the "options" parameter is set for this field, we assume it is because
              * the field type has multiple options. In order to make is more readable,
              * we try to replace the field value by the value label.
              *
              * This process is based on the fact that field types options always follow
              * the schema option_id => option_label.
              */
             if (isset($field['args']['options']) && is_array($field['args']['options'])) {
                 /* Make sure arrays are still readable */
                 if (is_array($value)) {
                     $new_values = array();
                     foreach ($value as $val) {
                         if (array_key_exists($val, $field['args']['options'])) {
                             array_push($new_values, $field['args']['options'][$val]);
                         }
                     }
                     /* Only if all original values were replaced we update the $value var. */
                     if (count($new_values) === count($value)) {
                         $value = $new_values;
                     }
                     $value = implode(', ', $value);
                 } else {
                     if (array_key_exists($value, $field['args']['options'])) {
                         $value = $field['args']['options'][$value];
                     }
                 }
             }
             $tmp = array('action' => '', 'label' => wpas_get_field_title($field), 'value' => $value, 'field_id' => $field['name']);
             switch ((int) $result) {
                 case 1:
                     $tmp['action'] = 'added';
                     break;
                 case 2:
                     $tmp['action'] = 'updated';
                     break;
                 case 3:
                     $tmp['action'] = 'deleted';
                     break;
             }
             /* Only add this to the log if something was done to the field value */
             if (!empty($tmp['action'])) {
                 $log[] = $tmp;
             }
         }
     }
     /**
      * Log the changes if any.
      */
     if (!empty($log)) {
         wpas_log($post_id, $log);
     }
     /**
      * wpas_save_custom_fields_before hook
      *
      * @since  3.0.0
      */
     do_action('wpas_save_custom_fields_after', $post_id);
     return $saved;
 }
Example #5
0
/**
 * Change a ticket status to open.
 *
 * @since  3.0.2
 * @param  integer         $ticket_id ID of the ticket to re-open
 * @return integer|boolean            ID of the post meta if exists, true on success or false on failure
 */
function wpas_reopen_ticket($ticket_id)
{
    if ('ticket' == get_post_type($ticket_id)) {
        $update = update_post_meta(intval($ticket_id), '_wpas_status', 'open');
        /* Log the action */
        wpas_log($ticket_id, __('The ticket was re-opened.', 'wpas'));
        /**
         * wpas_after_reopen_ticket hook
         *
         * @since  3.0.2
         */
        do_action('wpas_after_reopen_ticket', intval($ticket_id), $update);
        return $update;
    } else {
        return false;
    }
}