/** * Add plugin style settings. * * @param (array) $def Array of existing settings * @return (array) Updated settings */ function wpas_core_settings_style($def) { $settings = array('style' => array('name' => __('Style', 'wpas'), 'options' => array(array('name' => __('Theme', 'wpas'), 'id' => 'theme', 'type' => 'select', 'desc' => __('Which theme to use for the front-end.', 'wpas'), 'options' => wpas_list_themes(), 'default' => 'default'), array('name' => __('Theme Stylesheet', 'wpas'), 'id' => 'theme_stylesheet', 'type' => 'checkbox', 'desc' => __('Load the theme stylesheet. Don\'t uncheck if you don\'t know what this means', 'wpas'), 'default' => true), array('name' => __('Use editor in front-end', 'wpas'), 'id' => 'frontend_wysiwyg_editor', 'type' => 'checkbox', 'desc' => __('Show a editor editor for the ticket description when user submits a ticket.', 'wpas'), 'default' => true), array('name' => __('Colors', 'wpas'), 'type' => 'heading'), array('name' => __('Open Status', 'wpas'), 'id' => 'color_open', 'type' => 'color', 'default' => '#81d742'), array('name' => __('Closed Status', 'wpas'), 'id' => 'color_closed', 'type' => 'color', 'default' => '#dd3333'), array('name' => __('Old Status', 'wpas'), 'id' => 'color_old', 'type' => 'color', 'default' => '#dd9933'), array('name' => __('Awaiting Reply', 'wpas'), 'id' => 'color_awaiting_reply', 'type' => 'color', 'default' => '#0074a2')))); $status = wpas_get_post_status(); $defaults = apply_filters('wpas_labels_default_colors', array('queued' => '#1e73be', 'processing' => '#a01497', 'hold' => '#b56629', 'unknown' => '#169baa')); foreach ($status as $id => $label) { $option = array('name' => $label, 'id' => 'color_' . $id, 'type' => 'color', 'default' => isset($defaults[$id]) ? $defaults[$id] : $defaults['unknown']); array_push($settings['style']['options'], $option); } return array_merge($def, $settings); }
/** * Filter ticket data before insertion. * * Before inserting a new ticket in the database, * we check the post status and possibly overwrite it * with one of the registered custom status. * * @since 3.0.0 * * @param array $data Post data * @param array $postarr Original post data * * @return array Modified post data for insertion */ function wpas_filter_ticket_data($data, $postarr) { global $current_user; if (!isset($data['post_type']) || 'ticket' !== $data['post_type']) { return $data; } /** * If the ticket is being trashed we don't do anything. */ if ('trash' === $data['post_status']) { return $data; } /** * Do not affect auto drafts */ if ('auto-draft' === $data['post_status']) { return $data; } /** * Automatically set the ticket as processing if this is the first reply. */ if (user_can($current_user->ID, 'edit_ticket') && isset($postarr['ID'])) { $replies = wpas_get_replies(intval($postarr['ID'])); $agent_replied = false; if (0 !== count($replies)) { foreach ($replies as $reply) { if (user_can($reply->post_author, 'edit_ticket')) { $agent_replied = true; break; } } } if (false === $agent_replied && (!isset($_POST['post_status_override']) || 'queued' === $_POST['post_status_override'])) { $_POST['post_status_override'] = 'processing'; } } if (isset($_POST['post_status_override']) && !empty($_POST['post_status_override'])) { $status = wpas_get_post_status(); if (array_key_exists($_POST['post_status_override'], $status)) { $data['post_status'] = $_POST['post_status_override']; if ($postarr['original_post_status'] !== $_POST['post_status_override'] && isset($_POST['wpas_post_parent'])) { wpas_log(intval($_POST['wpas_post_parent']), sprintf(__('Ticket state changed to %s', 'awesome-support'), '«' . $status[$_POST['post_status_override']] . '»')); } } } return $data; }
/** * Custom callback for updating terms count. * * The function is based on the original WordPress function * _update_post_term_count but adapted to work with the plugin * custom status. * * @since 3.0.0 * @param array $terms List of terms attached to the post * @param object $taxonomy Taxonomy of update * @return void */ function wpas_update_ticket_tag_terms_count($terms, $taxonomy) { global $wpdb; $object_types = (array) $taxonomy->object_type; $post_status = wpas_get_post_status(); $allowed_status = array(); foreach ($post_status as $status => $label) { if (!in_array($status, $allowed_status)) { array_push($allowed_status, $status); } } foreach ($object_types as &$object_type) { list($object_type) = explode(':', $object_type); } $object_types = array_unique($object_types); if (false !== ($check_attachments = array_search('attachment', $object_types))) { unset($object_types[$check_attachments]); $check_attachments = true; } if ($object_types) { $object_types = esc_sql(array_filter($object_types, 'post_type_exists')); } foreach ((array) $terms as $term) { $count = 0; // Attachments can be 'inherit' status, we need to base count off the parent's status if so if ($check_attachments) { $count += (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_relationships}, {$wpdb->posts} p1 WHERE p1.ID = {$wpdb->term_relationships}.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM {$wpdb->posts} WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term)); } if ($object_types) { $count += (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_relationships}, {$wpdb->posts} WHERE {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id AND post_status IN ('" . implode("', '", $allowed_status) . "') AND post_type IN ('" . implode("', '", $object_types) . "') AND term_taxonomy_id = %d", $term)); } /** This action is documented in wp-includes/taxonomy.php */ do_action('edit_term_taxonomy', $term, $taxonomy); $wpdb->update($wpdb->term_taxonomy, compact('count'), array('term_taxonomy_id' => $term)); /** This action is documented in wp-includes/taxonomy.php */ do_action('edited_term_taxonomy', $term, $taxonomy); } }
/** * Display the post status. * * Gets the ticket status and formats it according to the plugin settings. * * @since 3.0.0 * * @param string $name Field / column name. This parameter is important as it is automatically passed by some * filters * @param integer $post_id ID of the post being processed * * @return string Formatted ticket status */ function wpas_cf_display_status($name, $post_id) { $status = wpas_get_ticket_status($post_id); if ('closed' === $status) { $label = __('Closed', 'awesome-support'); $color = wpas_get_option("color_{$status}", '#dd3333'); $tag = "<span class='wpas-label' style='background-color:{$color};'>{$label}</span>"; } else { $post = get_post($post_id); $post_status = $post->post_status; $custom_status = wpas_get_post_status(); if (!array_key_exists($post_status, $custom_status)) { $label = __('Open', 'awesome-support'); $color = wpas_get_option("color_{$status}", '#169baa'); $tag = "<span class='wpas-label' style='background-color:{$color};'>{$label}</span>"; } else { $defaults = array('queued' => '#1e73be', 'processing' => '#a01497', 'hold' => '#b56629'); $label = $custom_status[$post_status]; $color = wpas_get_option("color_{$post_status}", false); if (false === $color) { if (isset($defaults[$post_status])) { $color = $defaults[$post_status]; } else { $color = '#169baa'; } } $tag = "<span class='wpas-label' style='background-color:{$color};'>{$label}</span>"; } } echo $tag; }
/** * Get the ticket state slug. * * Gets the ticket status. If the ticket is closed nothing fancy. * If not, we return the ticket state instead of the "Open" status. * * The difference with wpas_get_ticket_status_state() is that only slugs are returned. No translation or capitalized * terms. * * @since 3.3 * * @param integer $post_id Post ID * * @return string Ticket status / state */ function wpas_get_ticket_status_state_slug($post_id) { $status = wpas_get_ticket_status($post_id); if ('closed' === $status) { return $status; } $post = get_post($post_id); $post_status = $post->post_status; $custom_status = wpas_get_post_status(); if (!array_key_exists($post_status, $custom_status)) { return 'open'; } return $post->post_status; }
/** * Get the tickets count by ticket status * * @since 3.2 * * @param string $state * @param string $status * * @return int Tickets count */ function wpas_get_ticket_count_by_status($state = '', $status = 'open') { $args = array(); $post_status = wpas_get_post_status(); // Make the state an array if (!is_array($state)) { $state = array_filter((array) $state); } // Sanitize the status if (!in_array($status, array('open', 'closed', 'any'))) { $status = 'open'; } // Restrict tickets to the specified status if (!empty($state)) { // Force open status if a state is defined. Who cares about counting closed "In Progress" tickets. $status = 'open'; // Make sure the requested ticket state is declared foreach ($state as $key => $s) { if (!array_key_exists($s, $post_status)) { unset($state[$key]); } } $args['post_status'] = $state; } // Maybe restrict the count to the current user only if (current_user_can('administrator') && false === (bool) wpas_get_option('admin_see_all') || !current_user_can('administrator') && current_user_can('edit_ticket') && false === (bool) wpas_get_option('agent_see_all')) { global $current_user; $args['meta_query'][] = array('key' => '_wpas_assignee', 'value' => $current_user->ID, 'compare' => '='); } return count(wpas_get_tickets($status, $args)); }
/** * Fix the ticket count in the ticket list screen * * The ticket count is wrong because it doesn't includes * the possible restrictions on user roles. * * @since 3.2 * * @param $views All available views in the ticket list screen * * @return array All views with accurate count */ function wpas_fix_tickets_count($views) { global $wp_query; $ticket_status = wpas_get_post_status(); // Our declared ticket status $status = 'open'; // Maybe apply filters if (isset($_GET['wpas_status'])) { switch ($_GET['wpas_status']) { case 'closed': $status = 'closed'; break; case '': $status = 'any'; break; } } foreach ($views as $view => $label) { if (array_key_exists($view, $ticket_status) || 'all' === $view) { $count = 'all' === $view ? wpas_get_ticket_count_by_status('', $status) : wpas_get_ticket_count_by_status($view, $status); $regex = '.*?(\\(.*\\))'; $replace = ''; if (preg_match_all("/" . $regex . "/is", $label, $matches)) { $replace = $matches[1][0]; } $label = trim(strip_tags(str_replace($replace, '', $label))); $class = isset($wp_query->query_vars['post_status']) && $wp_query->query_vars['post_status'] === $view || isset($wp_query->query_vars['post_status']) && 'all' === $view && $wp_query->query_vars['post_status'] == null ? ' class="current"' : ''; $link_query_args = 'all' === $view ? array('post_type' => 'ticket') : array('post_type' => 'ticket', 'post_status' => $view); $link = esc_url(add_query_arg($link_query_args, admin_url('edit.php'))); $views[$view] = sprintf('<a href="%1$s"%2$s>%3$s <span class="count">(%4$d)</span></a>', $link, $class, $label, $count); } } return $views; }
* * @since 3.3 */ // If this file is called directly, abort. if (!defined('WPINC')) { die; } global $post; // Get the user object $user = get_userdata($post->post_author); // Get tickets $open = wpas_get_tickets('open', array('posts_per_page' => apply_filters('wpas_user_profile_tickets_open_limit', 10), 'author' => $post->post_author)); $closed = wpas_get_tickets('closed', array('posts_per_page' => apply_filters('wpas_user_profile_tickets_closed_limit', 5), 'author' => $post->post_author)); // Sort open tickets $by_status = array(); $all_status = wpas_get_post_status(); foreach ($open as $t) { if (!is_a($t, 'WP_Post')) { continue; } if (!array_key_exists($t->post_status, $all_status)) { continue; } if (!array_key_exists($t->post_status, $by_status)) { $by_status[$t->post_status] = array(); } $by_status[$t->post_status][] = $t; } // Add the closed tickets in the list $by_status['closed'] = $closed; ?>
/** * Get the ticket state. * * Gets the ticket status. If the ticket is closed nothing fancy. * If not, we return the ticket state instead of the "Open" status. * * @since 3.1.5 * * @param integer $post_id Post ID * * @return string Ticket status / state */ function wpas_get_ticket_status_state($post_id) { $status = wpas_get_ticket_status($post_id); if ('closed' === $status) { $output = __('Closed', 'wpas'); } else { $post = get_post($post_id); $post_status = $post->post_status; $custom_status = wpas_get_post_status(); if (!array_key_exists($post_status, $custom_status)) { $output = __('Open', 'wpas'); } else { $output = $custom_status[$post_status]; } } return $output; }
/** * Update ticket status. * * Update the post_status of a ticket * using one of the custom status registered by the plugin * or its addons. * * @since 3.0.0 * @param integer $post_id ID of the ticket being updated * @param string $status New status to attribute * @return boolean True if the query was successfully executed */ function wpas_update_ticket_status($post_id, $status) { $custom_status = wpas_get_post_status(); if (!array_key_exists($status, $custom_status)) { return false; } $post = get_post($post_id); if (!$post || $post->post_status === $status) { return false; } $my_post = array('ID' => $post_id, 'post_status' => $status); $updated = wp_update_post($my_post); if (0 !== intval($updated)) { wpas_log($post_id, sprintf(__('Ticket state changed to «%s»', 'wpas'), $custom_status[$status])); } /** * wpas_ticket_status_updated hook * * @since 3.0.2 */ do_action('wpas_ticket_status_updated', $post_id, $status, $updated); return $updated; }
/** * Add quick ticket actions. * * Add options to change ticket state and status in the quick edit box. * * @since 3.0.0 * @param array $column_name ID of the current column * @param string $post_type Post type * @return void */ public function custom_quickedit_options($column_name, $post_type) { if ('ticket' !== $post_type) { return false; } if ('status' === $column_name) { $custom_status = wpas_get_post_status(); ?> <fieldset class="inline-edit-col-right inline-edit-ticket"> <div class="inline-edit-col column-<?php echo $column_name; ?> "> <div class="inline-edit-group"> <label class="inline-edit-group"> <span class="title"><?php _e('Ticket Status', 'wpas'); ?> </span> <select name="_wpas_status"> <option value="open"><?php _e('Open', 'wpas'); ?> </option> <option value="closed"><?php _e('Closed', 'wpas'); ?> </option> </select> </label> </div> <div class="inline-edit-group"> <label class="inline-edit-group"> <span class="title"><?php _e('Ticket State', 'wpas'); ?> </span> <select name="_wpas_state"> <?php foreach ($custom_status as $status_id => $status_label) { ?> <option value="<?php echo $status_id; ?> "><?php echo $status_label; ?> </option><?php } ?> </select> </label> </div> </div> </fieldset> <?php } }
/** * Register custom ticket status. * * @since 3.0.0 * @return void */ function wpas_register_post_status() { $status = wpas_get_post_status(); foreach ($status as $id => $custom_status) { $args = array('label' => $custom_status, 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, 'label_count' => _n_noop("{$custom_status} <span class='count'>(%s)</span>", "{$custom_status} <span class='count'>(%s)</span>", 'awesome-support')); register_post_status($id, $args); } /** * Hardcode the read and unread status used for replies. */ register_post_status('read', array('label' => _x('Read', 'Reply status', 'awesome-support'), 'public' => false)); register_post_status('unread', array('label' => _x('Unread', 'Reply status', 'awesome-support'), 'public' => false)); }
die; } global $pagenow, $post; /* Current status */ $ticket_status = get_post_meta(get_the_ID(), '_wpas_status', true); /** * Status action link * * @var string * @see admin/class-awesome-support-admin.php */ $action = in_array($ticket_status, array('closed', '')) ? wpas_get_open_ticket_url($post->ID) : wpas_get_close_ticket_url($post->ID); /** * Get available statuses. */ $statuses = wpas_get_post_status(); /* Get post status */ $post_status = isset($post) ? $post->post_status : ''; /* Get time */ if (isset($post)) { $date = human_time_diff(get_the_time('U', $post->ID), current_time('timestamp')); } ?> <div class="wpas-ticket-status submitbox"> <p> <strong><?php _e('Ticket status:', 'awesome-support'); ?> </strong> <?php if ('post-new.php' != $pagenow) {