base = $base; // Define the database table name. $this->table = 'to_' . strtolower( $this->base->plugin->account ) . '_log'; // Actions. add_filter( 'set-screen-option', array( $this, 'set_screen_options' ), 10, 3 ); add_action( 'current_screen', array( $this, 'run_log_table_bulk_actions' ) ); add_action( 'current_screen', array( $this, 'run_log_table_filters' ) ); add_action( 'admin_menu', array( $this, 'admin_meta_boxes' ) ); add_action( 'wp_loaded', array( $this, 'export' ) ); } /** * Activation routines for this Model * * @since 3.9.6 * * @global $wpdb WordPress DB Object */ public function activate() { global $wpdb; // Enable error output if WP_DEBUG is enabled. $wpdb->show_errors = true; // Create database table. $query = $wpdb->prepare( "CREATE TABLE IF NOT EXISTS %i ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `post_id` int(11) NOT NULL, `action` enum('publish','update','repost','bulk_publish') DEFAULT NULL, `request_sent` datetime NOT NULL, `profile_id` varchar(191) NOT NULL, `profile_name` varchar(191) NOT NULL DEFAULT '', `result` enum('success','test','pending','warning','error') NOT NULL DEFAULT 'success', `result_message` text, `status_text` text, `status_created_at` datetime DEFAULT NULL, `status_due_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `post_id` (`post_id`), KEY `action` (`action`), KEY `result` (`result`), KEY `profile_id` (`profile_id`) )", $wpdb->prefix . $this->table ); $query .= ' ' . $wpdb->get_charset_collate() . ' AUTO_INCREMENT=1'; $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Checks if the log is enabled * * @since 4.2.0 * * @return bool Logging Enabled */ public function is_enabled() { // Get Log Settings. $log_settings = $this->base->get_class( 'settings' )->get_option( 'log', false ); // Logging disabled if no settings. if ( ! $log_settings ) { return false; } // Logging disabled if no setting. if ( ! isset( $log_settings['enabled'] ) ) { return false; } // Return. return absint( $log_settings['enabled'] ); } /** * Sets values for options displayed in the Screen Options dropdown on the Logs * WP_List_Table * * @since 4.3.0 * * @param mixed $screen_option The value to save instead of the option value. Default false (to skip saving the current option). * @param string $option The option name. * @param string $value The option value. * @return string The option value */ public function set_screen_options( $screen_option, $option, $value ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter return $value; } /** * Defines options to display in the Screen Options dropdown on the Logs * WP_List_Table * * @since 4.3.0 */ public function add_screen_options() { add_screen_option( 'per_page', array( 'label' => __( 'Log Entries per Page', 'wp-to-buffer' ), 'default' => 20, 'option' => $this->base->plugin->filter_name . '_logs_per_page', ) ); // Initialize Logs WP_List_Table, as this will trigger WP_List_Table to add column options. $log_table = new \WPZinc\Social\Log_Table( $this->base ); } /** * Run any bulk actions on the Log WP_List_Table * * @since 3.9.6 */ public function run_log_table_bulk_actions() { // Get screen. $screen = $this->base->get_class( 'screen' )->get_current_screen(); // Bail if we're not on the Log screen. if ( $screen['screen'] !== 'log' ) { return; } // Bail if nonce is not valid. if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'bulk-wpzinc-social-log' ) ) { return; } // Get bulk action from the fields that might contain it. $bulk_action = array_values( array_filter( array( ( isset( $_REQUEST['bulk_action'] ) && $_REQUEST['bulk_action'] != -1 ? sanitize_text_field( wp_unslash( $_REQUEST['bulk_action'] ) ) : '' ), // phpcs:ignore Universal.Operators.StrictComparisons.LooseNotEqual ( isset( $_REQUEST['bulk_action2'] ) && $_REQUEST['bulk_action2'] != -1 ? sanitize_text_field( wp_unslash( $_REQUEST['bulk_action2'] ) ) : '' ), // phpcs:ignore Universal.Operators.StrictComparisons.LooseNotEqual ( isset( $_REQUEST['bulk_action3'] ) && ! empty( $_REQUEST['bulk_action3'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['bulk_action3'] ) ) : '' ), ) ) ); // Bail if no bulk action. if ( ! is_array( $bulk_action ) ) { return; } if ( ! count( $bulk_action ) ) { return; } // Setup notices class, enabling persistent storage. $this->base->get_class( 'notices' )->enable_store(); $this->base->get_class( 'notices' )->set_key_prefix( $this->base->plugin->filter_name . '_' . wp_get_current_user()->ID ); // Perform Bulk Action. switch ( $bulk_action[0] ) { /** * Delete Logs */ case 'delete': // Get Post IDs. if ( ! isset( $_REQUEST['ids'] ) ) { $this->base->get_class( 'notices' )->add_error_notice( __( 'No logs were selected for deletion.', 'wp-to-buffer' ) ); break; } // Delete Logs by IDs. $ids = array_unique( array_map( 'absint', $_REQUEST['ids'] ) ); $this->delete_by_ids( $ids ); // Add success notice. $this->base->get_class( 'notices' )->add_success_notice( sprintf( /* translators: Number of log entries deleted */ __( '%s Logs deleted.', 'wp-to-buffer' ), count( $ids ) ) ); break; /** * Delete All Logs */ case 'delete_all': // Delete Logs. $this->delete_all(); // Add success notice. $this->base->get_class( 'notices' )->add_success_notice( __( 'All Logs deleted.', 'wp-to-buffer' ) ); break; } // Redirect. wp_safe_redirect( 'admin.php?page=' . $this->base->plugin->name . '-' . $screen['screen'] ); die(); } /** * Redirect POST filters to a GET URL * * @since 3.9.6 */ public function run_log_table_filters() { // Get screen. $screen = $this->base->get_class( 'screen' )->get_current_screen(); // Bail if we're not on the Log screen. if ( $screen['screen'] !== 'log' ) { return; } // Bail if nonce is not valid. if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'bulk-wpzinc-social-log' ) ) { return; } $params = array(); foreach ( $this->base->get_class( 'common' )->get_log_filters() as $filter ) { if ( ! isset( $_POST[ $filter ] ) ) { continue; } if ( empty( $_POST[ $filter ] ) ) { continue; } $params[ $filter ] = sanitize_text_field( wp_unslash( $_POST[ $filter ] ) ); } // Include search parameter. if ( array_key_exists( 's', $_POST ) ) { $params['s'] = sanitize_text_field( wp_unslash( $_POST['s'] ) ); } // If params don't exist, exit. if ( ! count( $params ) ) { return; } // Add nonce. $params['_wpnonce'] = wp_create_nonce( 'bulk-wpzinc-social-log' ); // Redirect. wp_safe_redirect( 'admin.php?page=' . $this->base->plugin->name . '-' . $screen['screen'] . '&' . http_build_query( $params ) ); die(); } /** * Adds Metaboxes to Post Edit Screens * * @since 3.0.0 */ public function admin_meta_boxes() { // Only load if Logging is enabled and Displayed on Posts. $log_enabled = $this->is_enabled(); $log_display_on_posts = $this->base->get_class( 'settings' )->get_setting( 'log', '[display_on_posts]' ); if ( ! $log_enabled ) { return; } if ( ! $log_display_on_posts ) { return; } // Check if we need to hide the meta box by the logged in User's role. if ( wp_get_current_user() && is_array( wp_get_current_user()->roles ) && ! empty( wp_get_current_user()->roles ) ) { // Bail if we're hiding the meta boxes for the logged in User's role. if ( $this->base->get_class( 'settings' )->get_setting( 'hide_meta_box_by_roles', '[' . wp_get_current_user()->roles[0] . ']' ) ) { return; } } // Get Post Types. $post_types = $this->base->get_class( 'common' )->get_post_types(); // Add meta boxes for each Post Type. foreach ( $post_types as $post_type => $post_type_obj ) { add_meta_box( $this->base->plugin->name . '-log', sprintf( /* translators: Social Media Service Name (Buffer, Hootsuite) */ __( '%s Log', 'wp-to-buffer' ), $this->base->plugin->displayName ), array( $this, 'output_post_log' ), $post_type, 'normal', 'low' ); } } /** * Outputs the plugin's log of existing status update calls made to the API * * @since 3.0.0 * * @param WP_Post $post Post. */ public function output_post_log( $post ) { // Get log. $log = $this->get( $post->ID ); // Define URLs. $urls = array( 'refresh' => add_query_arg( array( $this->base->plugin->name . '-refresh-log' => 1 ), get_edit_post_link( $post->ID ) ), 'export' => add_query_arg( array( $this->base->plugin->name . '-export-log' => wp_create_nonce( $this->base->plugin->name . '-export-log' ) ), get_edit_post_link( $post->ID ) ), 'clear' => add_query_arg( array( $this->base->plugin->name . '-clear-log' => 1 ), get_edit_post_link( $post->ID ) ), ); // Load View. include_once $this->base->plugin->folder . 'lib/social/views/post-log.php'; } /** * Exports a Post's API log file in JSON format * * @since 3.0.0 */ public function export() { // Bail if nonce is not valid. if ( ! isset( $_REQUEST[ $this->base->plugin->name . '-export-log' ] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST[ $this->base->plugin->name . '-export-log' ] ) ), $this->base->plugin->name . '-export-log' ) ) { return; } // Bail if no post specified. if ( ! isset( $_GET['post'] ) ) { return; } // Check the user is logged in and can edit posts in order to access the log. if ( ! function_exists( 'current_user_can' ) ) { return; } if ( ! current_user_can( 'edit_post', absint( $_GET['post'] ) ) ) { return; } // Get log. $log = $this->get( absint( $_GET['post'] ) ); // Build JSON. $json = wp_json_encode( $log ); // Export. header( 'Content-type: application/x-msdownload' ); header( 'Content-Disposition: attachment; filename=log.json' ); header( 'Pragma: no-cache' ); header( 'Expires: 0' ); echo $json; // phpcs:ignore WordPress.Security.EscapeOutput exit(); } /** * Adds a log entry for the given Post ID * * @since 3.9.6 * * @param int $post_id Post ID. * @param array $log Log. * enum $action Action (publish,update,repost,bulk_publish). * datetime $request_sent Request Sent to API. * string $profile_id Profile ID. * string $profile_name Profile Name. * enum $result Result (success,test_mode,pending,error). * string $result_message Result Message. * string $status_text Status Text. * datetime $status_created_at Status Created At on API. * datetime $status_due_at Status Scheduled for Publication to Profile. */ public function add( $post_id, $log ) { global $wpdb; // Fetch Log Levels that are enabled in the Plugin Settings. $log_levels = $this->base->get_class( 'settings' )->get_setting( 'log', '[log_level]' ); // Bail if the Log Result doesn't match a level that we're saving to the log table. if ( ! in_array( $log['result'], $log_levels, true ) ) { return; } // Enable error output if WP_DEBUG is enabled. $wpdb->show_errors(); // Add Post ID to log. $log['post_id'] = absint( $post_id ); // Insert Log. $result = $wpdb->insert( $wpdb->prefix . $this->table, $log ); } /** * Retrieves the log for the given Post ID * * @since 3.0.0 * * @param int $post_id Post ID. * @return array Log */ public function get( $post_id ) { global $wpdb; // Get log. $log = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE post_id = %d ORDER BY id DESC', $wpdb->prefix . $this->table, absint( $post_id ) ), ARRAY_A ); /** * Filters the log entries before output. * * @since 3.0.0 * * @param array $log Post Log. * @param int $post_id Post ID. */ $log = apply_filters( $this->base->plugin->filter_name . '_get_log', $log, $post_id ); // Return. return $log; } /** * Returns key/value Profile ID and Name pairs based on all unique * Profile IDs in the Log table * * @since 3.9.6 * * @return array */ public function get_profile_id_names() { global $wpdb; $results = $wpdb->get_results( $wpdb->prepare( 'SELECT profile_id, profile_name FROM %i GROUP BY profile_id ORDER BY profile_name DESC', $wpdb->prefix . $this->table ), ARRAY_A ); if ( ! $results || ! count( $results ) ) { return array(); } $profiles = array(); foreach ( $results as $result ) { if ( empty( $result['profile_id'] ) ) { continue; } $profiles[ $result['profile_id'] ] = ( empty( $result['profile_name'] ) ? __( 'Unknown', 'wp-to-buffer' ) : $result['profile_name'] ); } return $profiles; } /** * Defines the available Log Result Options * * @since 4.2.0 * * @return array Result Options (success,test,warning,error). */ public function get_result_options() { // Define log result options. $result_options = array( 'success' => __( 'Success', 'wp-to-buffer' ), 'test' => __( 'Test', 'wp-to-buffer' ), 'warning' => __( 'Warning', 'wp-to-buffer' ), 'error' => __( 'Error', 'wp-to-buffer' ), ); /** * Defines the available result options * * @since 4.2.0 * * @param array $result_options Result Options. */ $result_options = apply_filters( $this->base->plugin->filter_name . '_log_get_result_options', $result_options ); // Return filtered results. return $result_options; } /** * Returns the available Log Levels * * @since 4.2.0 * * @return array Log Levels */ public function get_level_options() { // Define log levels. $log_levels = array( 'success' => __( 'Success', 'wp-to-buffer' ), 'test' => __( 'Tests', 'wp-to-buffer' ), 'pending' => __( 'Pending', 'wp-to-buffer' ), 'warning' => __( 'Warnings', 'wp-to-buffer' ), 'error' => __( 'Errors', 'wp-to-buffer' ), ); /** * Defines the available log levels * * @since 4.2.0 * * @param array $log_levels Log Levels. */ $log_levels = apply_filters( $this->base->plugin->filter_name . '_log_get_log_levels', $log_levels ); // Return filtered results. return $log_levels; } /** * Searches logs by the given key/value pairs * * @since 3.9.6 * * @param string $order_by Order Results By. * @param string $order Order (asc|desc). * @param int $page Pagination Offset (default: 0). * @param int $per_page Number of Results to Return (default: 20). * @param mixed $params Query Parameters (false = all records). * @return array Log entries */ public function search( $order_by, $order, $page = 0, $per_page = 20, $params = false ) { global $wpdb; // Build where clauses. $where = $this->build_where_clause( $params ); // Prepare query. $query = $wpdb->prepare( 'SELECT * FROM %i LEFT JOIN %i ON %i.post_id = %i.ID', $wpdb->prefix . $this->table, $wpdb->posts, $wpdb->prefix . $this->table, $wpdb->posts ); // Add where clauses. if ( $where !== false ) { $query .= ' WHERE ' . $where; } // Order. $query .= $wpdb->prepare( ' ORDER BY %i.%i', $wpdb->prefix . $this->table, $order_by ); $query .= ' ' . ( strtolower( $order ) === 'asc' ? 'ASC' : 'DESC' ); // Limit. if ( $page > 0 && $per_page > 0 ) { $query .= $wpdb->prepare( ' LIMIT %d, %d', ( ( $page - 1 ) * $per_page ), $per_page ); } // Run and return query results. return $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Gets the number of log records found for the given query parameters * * @since 3.9.6 * * @param mixed $params Query Parameters (false = all records). * @return int Total Records */ public function total( $params = false ) { global $wpdb; // Build where clauses. $where = $this->build_where_clause( $params ); // Prepare query. $query = $wpdb->prepare( 'SELECT COUNT(%i.id) FROM %i LEFT JOIN %i ON %i.post_id = %i.ID', $wpdb->prefix . $this->table, $wpdb->prefix . $this->table, $wpdb->posts, $wpdb->prefix . $this->table, $wpdb->posts ); // Add where clauses. if ( $where !== false ) { $query .= ' WHERE ' . $where; } // Run and return total records found. return $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } /** * Builds a WHERE SQL clause based on the given column key/values * * @since 3.9.6 * * @param array $params Query Parameters (false = all records). * @return string WHERE SQL clause */ private function build_where_clause( $params ) { global $wpdb; // Bail if no params. if ( ! $params ) { return false; } // Build where clauses. $where = array(); if ( $params !== false && is_array( $params ) && count( $params ) > 0 ) { foreach ( $params as $key => $value ) { // Skip blank params. if ( empty( $value ) ) { continue; } // Build condition based on the key. switch ( $key ) { case 'post_title': $where[] = $wpdb->prepare( '(%i LIKE %s OR status_text LIKE %s OR result_message LIKE %s)', $key, '%' . $wpdb->esc_like( $value ) . '%', '%' . $wpdb->esc_like( $value ) . '%', '%' . $wpdb->esc_like( $value ) . '%' ); break; case 'request_sent_start_date': if ( ! empty( $params['request_sent_end_date'] ) && $params['request_sent_start_date'] > $params['request_sent_end_date'] ) { $where[] = $wpdb->prepare( 'request_sent <= %s', $value . ' 23:59:59' ); } else { $where[] = $wpdb->prepare( 'request_sent >= %s', $value . ' 00:00:00' ); } break; case 'request_sent_end_date': if ( ! empty( $params['request_sent_start_date'] ) && $params['request_sent_start_date'] > $params['request_sent_end_date'] ) { $where[] = $wpdb->prepare( 'request_sent >= %s', $value . ' 00:00:00' ); } else { $where[] = $wpdb->prepare( 'request_sent <= %s', $value . ' 23:59:59' ); } break; default: $where[] = $wpdb->prepare( '%i = %s', $key, $value ); break; } } } if ( ! count( $where ) ) { return false; } return implode( ' AND ', $where ); } /** * Deletes a single Log entry for the given Log ID * * @since 3.9.6 * * @param array $id Log ID. * @return bool Success */ public function delete_by_id( $id ) { global $wpdb; return $wpdb->delete( $wpdb->prefix . $this->table, array( 'id' => absint( $id ), ) ); } /** * Deletes multiple Log entries for the given Log IDs * * @since 3.9.6 * * @param array $ids Log IDs. * @return bool Success */ public function delete_by_ids( $ids ) { global $wpdb; return $wpdb->query( $wpdb->prepare( sprintf( 'DELETE FROM %s WHERE id IN (%s)', $wpdb->prefix . $this->table, // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared implode( ',', array_fill( 0, count( $ids ), '%d' ) ) ), $ids ) ); } /** * Deletes Log entries for the given Post ID * * @since 3.7.9 * * @param int $post_id Post ID. * @return bool Success */ public function delete_by_post_id( $post_id ) { global $wpdb; return $wpdb->delete( $wpdb->prefix . $this->table, array( 'post_id' => absint( $post_id ), ) ); } /** * Deletes Log entries for the given Post ID and Pending Status * * @since 3.7.9 * * @param int $post_id Post ID. * @return bool Success */ public function delete_pending_by_post_id( $post_id ) { global $wpdb; return $wpdb->delete( $wpdb->prefix . $this->table, array( 'post_id' => absint( $post_id ), 'result' => 'pending', ) ); } /** * Deletes Log entries for the given Post ID and Action that have * a pending Status * * @since 3.7.9 * * @param int $post_id Post ID. * @param string $action Action. * @return bool Success */ public function delete_pending_by_post_id_and_action( $post_id, $action = 'publish' ) { global $wpdb; return $wpdb->delete( $wpdb->prefix . $this->table, array( 'post_id' => absint( $post_id ), 'result' => 'pending', 'action' => $action, ) ); } /** * Deletes all Log entries older than the given date * * @since 3.9.8 * * @param datetime $date_time Date and Time. * @return bool Success */ public function delete_by_request_sent_cutoff( $date_time ) { global $wpdb; // Run query. return $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE request_sent < %s', $wpdb->prefix . $this->table, $date_time ) ); } /** * Deletes all Log entries * * @since 3.9.6 * * @return bool Success */ public function delete_all() { global $wpdb; return $wpdb->query( $wpdb->prepare( 'TRUNCATE TABLE %i', $wpdb->prefix . $this->table ) ); } /** * Wrapper for PHP's error_log() function, which will only write * to the error log if: * - WP_DEBUG = true * - WP_DEBUG_DISPLAY = false * - WP_DEBUG_LOG = true * * This will ensure that the output goes to wp-content/debug.log * * @since 3.6.8 * * @param mixed $data Data to log. * @param mixed $backtrace Backtrace data from debug_backtrace(). */ public function add_to_debug_log( $data = '', $backtrace = false ) { // Add the data to our class array for possible output in the UI. $this->debug_log[] = $data; // Bail if Logging isn't enabled in the Plugin. if ( ! $this->is_enabled() ) { return; } // Bail if no WP_DEBUG, or it's false. if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) { return; } // Bail if no WP_DEBUG_DISPLAY, or it's true. if ( ! defined( 'WP_DEBUG_DISPLAY' ) || WP_DEBUG_DISPLAY ) { return; } // Bail if no WP_DEBUG_LOG, or it's false. if ( ! defined( 'WP_DEBUG_LOG' ) || ! WP_DEBUG_LOG ) { return; } // If we need to fetch the class and function name to prefix to the log entry, do so now. $prefix_data = ''; if ( $backtrace !== false ) { if ( isset( $backtrace[0] ) ) { if ( isset( $backtrace[0]['class'] ) ) { $prefix_data .= $backtrace[0]['class']; } if ( isset( $backtrace[0]['function'] ) ) { $prefix_data .= '::' . $backtrace[0]['function'] . '()'; } } } // If the data is empty, change it to 'called'. if ( empty( $data ) ) { $data = 'Called'; } // If the data is an array or object, convert it to a string. if ( is_array( $data ) || is_object( $data ) ) { $data = print_r( $data, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions } // If we're prefixing the log entry, do so now. if ( ! empty( $prefix_data ) ) { $data = $prefix_data . ': ' . $data; } // Add the data to the error log, which will appear in wp-content/debug.log. error_log( $data ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions } /** * Returns contents of this class' debug_log array, which comprise of * items added using add_to_debug_log() above. * * @since 4.1.8 * * @return array */ public function get_debug_log() { return $this->debug_log; } /** * Takes a given array of log results, and builds HTML table row output * that can be used by: * - Posts > Log Meta Box * - Bulk Publish > Results Screen * * @since 3.7.9 * * @param array $log Log Results. * @param bool $is_wp_list_table Is Output for a WP_List_Table (adds checkbox and Post ID columns). * @param mixed $columns Displayed, Hidden and Sortable Columns (false = display all). * @return string Table Rows HTML */ public function build_log_table_output( $log, $is_wp_list_table = false, $columns = false ) { // Define columns. if ( is_array( $columns ) ) { list( $columns, $hidden, $sortable, $primary ) = $columns; $colspan = ( $is_wp_list_table ? 10 : 8 ); } else { $columns = array(); $hidden = array(); $colspan = ( $is_wp_list_table ? 10 : 8 ); } // Define HTML output. $html = ''; // If no results, return a single row. if ( ! $log || ! is_array( $log ) || count( $log ) === 0 ) { $html = ' ' . sprintf( /* translators: Social Media Service Name (Buffer, Hootsuite) */ __( 'No log entries exist, or no status updates have been sent to %s.', 'wp-to-buffer' ), $this->base->plugin->account ) . ' '; return $html; } // Get Post Actions. $post_actions = $this->base->get_class( 'common' )->get_post_actions(); // Build Table HTML. foreach ( $log as $count => $result ) { // If output is for a WP_List_Table, add checkbox and Post ID. if ( $is_wp_list_table ) { $checkbox_id = ' ' . $result['post_id'] . ' '; } // Add row to HTML. $html .= ' ' . ( $is_wp_list_table ? $checkbox_id : '' ) . ' ' . get_date_from_gmt( $result['request_sent'], get_option( 'date_format' ) . ' H:i:s' ) . ' ' . ( isset( $post_actions[ $result['action'] ] ) ? $post_actions[ $result['action'] ] : ' ' ) . ' ' . ( empty( $result['profile_name'] ) ? __( 'N/A', 'wp-to-buffer' ) : $result['profile_name'] ) . ' ' . ( empty( $result['status_text'] ) ? __( 'N/A', 'wp-to-buffer' ) : nl2br( $result['status_text'] ) ) . ' ' . ucfirst( $result['result'] ) . ''; switch ( $result['result'] ) { case 'success': $html .= ' ' . $result['result_message'] . ' ' . get_date_from_gmt( $result['status_created_at'], get_option( 'date_format' ) . ' H:i:s' ) . ' ' . ( ( $result['status_due_at'] !== '0000-00-00 00:00:00' ) ? get_date_from_gmt( $result['status_due_at'], get_option( 'date_format' ) . ' H:i:s' ) : '' ) . ''; break; case 'test': $html .= ' ' . $result['result_message'] . ' ' . get_date_from_gmt( $result['status_created_at'], get_option( 'date_format' ) . ' H:i:s' ) . ' ' . ( ( $result['status_due_at'] !== '0000-00-00 00:00:00' ) ? get_date_from_gmt( $result['status_due_at'], get_option( 'date_format' ) . ' H:i:s' ) : '' ) . ''; break; default: $html .= ' ' . nl2br( $result['result_message'] ) . '    '; break; } $html .= ''; } // Return. return $html; } }