Inventory_Presser_Admin_Customize_Dashboard
Contents
Description Description
An object that customizes the administrator dashboard to make managing an inventory of vehicles easy.
Source Source
File: includes/admin/class-admin-customize-dashboard.php
class Inventory_Presser_Admin_Customize_Dashboard { const NONCE_DELETE_ALL_MEDIA = 'invp_delete_all_media'; /** * add_columns_to_vehicles_table * * Adds slugs to the post table columns array so the dashboard list of * vehicles is more informative than the vanilla list for posts. * * @param array $column * @return array */ function add_columns_to_vehicles_table( $column ) { // add our columns $column[ apply_filters( 'invp_prefix_meta_key', 'stock_number' ) ] = __( 'Stock #', 'inventory-presser' ); $column[ apply_filters( 'invp_prefix_meta_key', 'color' ) ] = __( 'Color', 'inventory-presser' ); $column[ apply_filters( 'invp_prefix_meta_key', 'odometer' ) ] = __( 'Odometer', 'inventory-presser' ); $column[ apply_filters( 'invp_prefix_meta_key', 'price' ) ] = __( 'Price', 'inventory-presser' ); $column[ apply_filters( 'invp_prefix_meta_key', 'photo_count' ) ] = __( 'Photos', 'inventory-presser' ); $column[ apply_filters( 'invp_prefix_meta_key', 'thumbnail' ) ] = __( 'Thumbnail', 'inventory-presser' ); // remove the date and tags columns unset( $column['date'] ); unset( $column['tags'] ); return $column; } /** * add_meta_boxes_to_cpt * * Adds meta boxes to the editor when editing vehicles. * * @return void */ function add_meta_boxes_to_cpt() { // Add a meta box to the New/Edit post page // add_meta_box('vehicle-meta', 'Attributes', array( $this, 'meta_box_html_vehicle' ), INVP::POST_TYPE, 'normal', 'high' ); // and another for prices // add_meta_box('prices-meta', 'Prices', array( $this, 'meta_box_html_prices' ), INVP::POST_TYPE, 'normal', 'high' ); // Add another meta box to the New/Edit post page add_meta_box( 'options-meta', 'Optional equipment', array( $this, 'meta_box_html_options' ), INVP::POST_TYPE, 'normal', 'high' ); // Add a meta box to the side column for a featured vehicle checkbox add_meta_box( 'featured', 'Featured Vehicle', array( $this, 'meta_box_html_featured' ), INVP::POST_TYPE, 'side', 'low' ); } /** * add_vehicles_to_admin_bar * * Adds a Vehicle button to the Admin Bar * * @return void */ function add_vehicles_to_admin_bar() { // do not do this if we are already looking at the dashboard if ( is_admin() ) { return; } global $wp_admin_bar; $wp_admin_bar->add_node( array( 'id' => 'wp-admin-bar-vehicles', 'title' => __( 'Vehicles', 'inventory-presser' ), 'href' => admin_url( 'edit.php?post_type=' . INVP::POST_TYPE ), 'parent' => 'site-name', ) ); } /** * annotate_add_media_button * * Adds HTML near the Add Media button on the classic editor. * * @param mixed $editor_id * @return void */ function annotate_add_media_button( $editor_id ) { if ( 'content' != $editor_id ) { return; } printf( '%s<span id="media-annotation" class="annotation">%s</span>', $this->create_delete_all_post_attachments_button(), $this->create_add_media_button_annotation() ); } /** * change_post_updated_messages * * Changes the messages shown to users in the editor when changes are made * to the post object. * * @param array $msgs * @return array */ function change_post_updated_messages( $msgs ) { global $post; $view_link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( get_permalink( $post->ID ) ), __( 'View vehicle', 'inventory-presser' ) ); $preview_link = sprintf( '<a target="_blank" href="%1$s">%2$s</a>', esc_url( get_preview_post_link( $post->ID ) ), __( 'Preview vehicle', 'inventory-presser' ) ); $scheduled_date = date_i18n( __( 'M j, Y @ H:i', 'inventory-presser' ), strtotime( $post->post_date ) ); $msgs[ INVP::POST_TYPE ] = array( 0 => '', 1 => __( 'Vehicle updated. ', 'inventory-presser' ) . $view_link, 2 => __( 'Custom field updated.', 'inventory-presser' ), 3 => __( 'Custom field updated.', 'inventory-presser' ), 4 => __( 'Vehicle updated.', 'inventory-presser' ), 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Vehicle restored to revision from %s.', 'inventory-presser' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, 6 => __( 'Vehicle published. ', 'inventory-presser' ) . $view_link, 7 => __( 'Vehicle saved.', 'inventory-presser' ), 8 => __( 'Vehicle submitted. ', 'inventory-presser' ) . $preview_link, 9 => sprintf( __( 'Vehicle scheduled to list on <strong>%s</strong>. ', 'inventory-presser' ), $scheduled_date ) . $preview_link, 10 => __( 'Vehicle draft updated. ', 'inventory-presser' ) . $preview_link, ); return $msgs; } /** * change_taxonomy_show_ui_attributes * * When the user flips the "Show All Taxonomies" setting switch, this * method changes the taxonomy registration so they are shown. * * @param array $taxonomy_data * @return array */ function change_taxonomy_show_ui_attributes( $taxonomy_data ) { for ( $i = 0; $i < sizeof( $taxonomy_data ); $i++ ) { if ( ! isset( $taxonomy_data[ $i ]['args']['show_in_menu'] ) ) { continue; } $taxonomy_data[ $i ]['args']['show_in_menu'] = true; $taxonomy_data[ $i ]['args']['show_ui'] = true; } return $taxonomy_data; } /** * create_add_media_button_annotation * * Computes the number of attachments on vehicles so the number can be * shown in the classic editor near the Add Media button. * * @return string */ function create_add_media_button_annotation() { global $post; if ( ! is_object( $post ) && isset( $_POST['post_ID'] ) ) { /** * This function is being called via AJAX and the * post_id is incoming, so get the post */ $post = get_post( intval( $_POST['post_ID'] ) ); } if ( INVP::POST_TYPE != $post->post_type ) { return ''; } $attachments = get_children( array( 'post_parent' => $post->ID, 'post_type' => 'attachment', 'posts_per_page' => -1, ) ); $counts = array( 'image' => 0, 'video' => 0, 'text' => 0, 'PDF' => 0, 'other' => 0, ); foreach ( $attachments as $attachment ) { switch ( $attachment->post_mime_type ) { case 'image/jpeg': case 'image/png': case 'image/gif': $counts['image']++; break; case 'video/mpeg': case 'video/mp4': case 'video/quicktime': $counts['video']++; break; case 'text/csv': case 'text/plain': case 'text/xml': $counts['text']++; break; case 'application/pdf': $counts['PDF']++; break; default: $counts['other']++; break; } } if ( 0 < ( $counts['image'] + $counts['video'] + $counts['text'] + $counts['PDF'] + $counts['other'] ) ) { $note = ''; foreach ( $counts as $key => $count ) { if ( 0 < $count ) { if ( '' != $note ) { $note .= ', '; } $note .= $count . ' ' . $key . ( 1 != $count ? 's' : '' ); } } return $note; } return '0 photos'; } /** * create_delete_all_post_attachments_button * * Creates HTML that renders a button that says "Delete All Media" that will * be placed near the Add Media button. * * @return string */ function create_delete_all_post_attachments_button() { global $post; if ( ! is_object( $post ) || ! isset( $post->ID ) ) { return ''; } // does this post have attachments? $post = get_post( $post->ID ); if ( INVP::POST_TYPE != $post->post_type ) { return ''; } $attachments = get_children( array( 'post_parent' => $post->ID, 'post_type' => 'attachment', 'posts_per_page' => -1, ) ); if ( 0 === sizeof( $attachments ) ) { return ''; } return sprintf( '<button type="button" id="delete-media-button" class="button" onclick="delete_all_post_attachments();">' . '<span class="wp-media-buttons-icon"></span> %s</button>', __( 'Delete All Media', 'inventory-presser' ) ); } /** * delete_all_post_attachments * * Deletes all a post's attachments. The callback behind the Delete All * Media button. * * @return void */ function delete_all_post_attachments() { if ( empty( $_POST['_ajax_nonce'] ) || ! wp_verify_nonce( $_POST['_ajax_nonce'], self::NONCE_DELETE_ALL_MEDIA ) ) { return; } $post_id = isset( $_POST['post_ID'] ) ? $_POST['post_ID'] : 0; if ( ! isset( $post_id ) ) { return; // Will die in case you run a function like this: delete_post_media($post_id); if you will remove this line - ALL ATTACHMENTS WHO HAS A PARENT WILL BE DELETED PERMANENTLY! } elseif ( 0 == $post_id ) { return; // Will die in case you have 0 set. there's no page id called 0 :) } elseif ( is_array( $post_id ) ) { return; // Will die in case you place there an array of pages. } else { INVP::delete_attachments( $post_id ); } } /** * enable_order_by_attachment_count * * Handle the ORDER BY on the vehicle list (edit.php) when sorting by photo * count. * * @param array $pieces * @param WP_Query $query * @return array */ function enable_order_by_attachment_count( $pieces, $query ) { if ( ! is_admin() ) { return $pieces; } /** * We only want our code to run in the main WP query * AND if an orderby query variable is designated. */ if ( $query->is_main_query() && ( $orderby = $query->get( 'orderby' ) ) ) { // Get the order query variable - ASC or DESC $order = strtoupper( $query->get( 'order' ) ); // Make sure the order setting qualifies. If not, set default as ASC if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) ) { $order = 'ASC'; } if ( apply_filters( 'invp_prefix_meta_key', 'photo_count' ) == $orderby || apply_filters( 'invp_prefix_meta_key', 'thumbnail' ) == $orderby ) { global $wpdb; $pieces['orderby'] = "( SELECT COUNT( ID ) FROM {$wpdb->posts} forget WHERE post_parent = {$wpdb->posts}.ID ) $order, " . $pieces['orderby']; } } return $pieces; } /** * hooks * * Adds hooks * * @return void */ function hooks() { add_filter( 'posts_clauses', array( $this, 'enable_order_by_attachment_count' ), 1, 2 ); // Save custom post meta and term relationships when posts are saved add_action( 'save_post_' . INVP::POST_TYPE, array( $this, 'save_vehicle_post_meta' ), 10, 3 ); add_action( 'save_post_' . INVP::POST_TYPE, array( $this, 'save_vehicle_taxonomy_terms' ), 10, 2 ); // Add columns to the table that lists all the Vehicles on edit.php add_filter( 'manage_' . INVP::POST_TYPE . '_posts_columns', array( $this, 'add_columns_to_vehicles_table' ) ); // Populate the columns we added to the Vehicles table add_action( 'manage_' . INVP::POST_TYPE . '_posts_custom_column', array( $this, 'populate_columns_we_added_to_vehicles_table' ), 10, 2 ); // Make our added columns to the Vehicles table sortable add_filter( 'manage_edit-' . INVP::POST_TYPE . '_sortable_columns', array( $this, 'make_vehicles_table_columns_sortable' ) ); // Implement the orderby for each of these added columns add_filter( 'pre_get_posts', array( $this, 'vehicles_table_columns_orderbys' ) ); add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes_to_cpt' ) ); // Move all "advanced" meta boxes above the default editor // http://wordpress.stackexchange.com/a/88103 add_action( 'edit_form_after_title', array( $this, 'move_advanced_meta_boxes' ) ); // Move the "Tags" metabox below the meta boxes for vehicle custom taxonomies add_action( 'add_meta_boxes', array( $this, 'move_tags_meta_box' ), 0 ); // Load our scripts add_action( 'admin_enqueue_scripts', array( $this, 'load_scripts' ) ); // Add some content next to the "Add Media" button add_action( 'media_buttons', array( $this, 'annotate_add_media_button' ) ); // Define an AJAX handler for the 'Delete All Media' button add_filter( 'wp_ajax_delete_all_post_attachments', array( $this, 'delete_all_post_attachments' ) ); // Make our Add Media button annotation available from an AJAX call add_action( 'wp_ajax_output_add_media_button_annotation', array( $this, 'output_add_media_button_annotation' ) ); // Add a link to the Settings page on the plugin management page add_filter( 'plugin_action_links_' . INVP_PLUGIN_BASE, array( $this, 'insert_settings_link' ), 2, 2 ); // Add a link to the main menu of the Admin bar add_action( 'admin_bar_menu', array( $this, 'add_vehicles_to_admin_bar' ), 100 ); $options = INVP::settings(); // If the Show All Taxonomies setting is checked, change the way we register taxonomies if ( isset( $options['show_all_taxonomies'] ) && $options['show_all_taxonomies'] ) { add_filter( 'invp_taxonomy_data', array( $this, 'change_taxonomy_show_ui_attributes' ) ); } // Change some messages in the dashboard the user sees when updating vehicles add_filter( 'post_updated_messages', array( $this, 'change_post_updated_messages' ) ); } /** * insert_settings_link * * Adds a link to the settings page near the Activate | Delete links on the * list of plugins on the Plugins page. * * @param array $links * @return array */ function insert_settings_link( $links ) { $url = admin_url( sprintf( 'edit.php?post_type=%s&page=dealership-options', INVP::POST_TYPE ) ); $links[] = sprintf( '<a href="%s">%s</a>', $url, __( 'Settings', 'inventory-presser' ) ); return $links; } /** * load_scripts * * Includes JavaScripts and stylesheets that power our changes to the * dashboard. * * @param string $hook * @return void */ function load_scripts( $hook ) { wp_enqueue_style( 'my-admin-theme', plugins_url( '/css/wp-admin.min.css', INVP_PLUGIN_FILE_PATH ) ); wp_register_script( 'invp-js', plugins_url( '/js/admin.min.js', INVP_PLUGIN_FILE_PATH ) ); wp_enqueue_script( 'invp-js' ); // Provide data to JavaScript for the editor wp_add_inline_script( 'invp-js', 'const invp = ' . json_encode( array( 'hull_materials' => apply_filters( 'invp_default_hull_materials', array( 'Aluminum', 'Carbon Fiber', 'Composite', 'Ferro-Cement', 'Fiberglass', 'Hypalon', 'Other', 'PVC', 'Steel', 'Wood', ) ), 'miles_word' => apply_filters( 'invp_odometer_word', 'miles' ), 'meta_prefix' => INVP::meta_prefix(), 'payment_frequencies' => apply_filters( 'invp_default_payment_frequencies', array( 'Monthly' => 'monthly', 'Weekly' => 'weekly', 'Bi-weekly' => 'biweekly', 'Semi-monthly' => 'semimonthly', ) ), 'title_statuses' => apply_filters( 'invp_default_title_statuses', array( 'Unspecified', 'Clear', 'Clean', 'Flood, Water Damage', 'Lemon and Manufacturers Buyback', 'Rebuild, Rebuildable, and Reconstructed', 'Salvage', 'Other', ) ), 'delete_all_media_nonce' => wp_create_nonce( self::NONCE_DELETE_ALL_MEDIA ), ) ), 'before' ); } /** * make_vehicles_table_columns_sortable * * Declares which of our custom columns on the list of posts are sortable. * * @param array $columns * @return array */ function make_vehicles_table_columns_sortable( $columns ) { $custom = array( // meta column id => sortby value used in query apply_filters( 'invp_prefix_meta_key', 'color' ) => apply_filters( 'invp_prefix_meta_key', 'color' ), apply_filters( 'invp_prefix_meta_key', 'odometer' ) => apply_filters( 'invp_prefix_meta_key', 'odometer' ), apply_filters( 'invp_prefix_meta_key', 'price' ) => apply_filters( 'invp_prefix_meta_key', 'price' ), apply_filters( 'invp_prefix_meta_key', 'stock_number' ) => apply_filters( 'invp_prefix_meta_key', 'stock_number' ), apply_filters( 'invp_prefix_meta_key', 'photo_count' ) => apply_filters( 'invp_prefix_meta_key', 'photo_count' ), apply_filters( 'invp_prefix_meta_key', 'thumbnail' ) => apply_filters( 'invp_prefix_meta_key', 'thumbnail' ), ); return wp_parse_args( $custom, $columns ); } /** * meta_box_html_featured * * Creates an editor meta box to help users mark vehicles as featured. * * @param WP_Post $post * @return void */ function meta_box_html_featured( $post ) { $meta_key = apply_filters( 'invp_prefix_meta_key', 'featured' ); printf( '<input type="checkbox" id="%s" name="%s" value="1"%s><label for="%s">%s</label>', $meta_key, $meta_key, checked( '1', INVP::get_meta( $meta_key, $post->ID ), false ), $meta_key, __( 'Featured in Slideshows', 'inventory-presser' ) ); } /** * meta_box_html_options * * Creates a meta box to help the user see and manage vehicle options while * editing a vehicle post. * * @param WP_Post $post * @return void */ function meta_box_html_options( $post ) { $options = apply_filters( 'invp_default_options', array( __( '3rd Row Seats', 'inventory-presser' ), __( 'Air Bags', 'inventory-presser' ), __( 'Air Conditioning', 'inventory-presser' ), __( 'Alloy Wheels', 'inventory-presser' ), __( 'Aluminum Wheels', 'inventory-presser' ), __( 'AM/FM Stereo', 'inventory-presser' ), __( 'Anti-lock Brakes', 'inventory-presser' ), __( 'Backup Camera', 'inventory-presser' ), __( 'Bed Cap', 'inventory-presser' ), __( 'Bluetooth, Hands Free', 'inventory-presser' ), __( 'Cassette', 'inventory-presser' ), __( 'CD Player', 'inventory-presser' ), __( 'Cell or Intergrated Cell Phone', 'inventory-presser' ), __( 'Cloth Seats', 'inventory-presser' ), __( 'Conversion Package', 'inventory-presser' ), __( 'Convertible', 'inventory-presser' ), __( 'Cooled Seats', 'inventory-presser' ), __( 'Cruise Control', 'inventory-presser' ), __( 'Custom Paint', 'inventory-presser' ), __( 'Disability Equipped', 'inventory-presser' ), __( 'Dual Sliding Doors', 'inventory-presser' ), __( 'DVD Player', 'inventory-presser' ), __( 'Extended Cab', 'inventory-presser' ), __( 'Fog Lights', 'inventory-presser' ), __( 'Heated Seats', 'inventory-presser' ), __( 'Keyless Entry', 'inventory-presser' ), __( 'Leather Seats', 'inventory-presser' ), __( 'Lift Kit', 'inventory-presser' ), __( 'Long Bed', 'inventory-presser' ), __( 'Memory Seat(s)', 'inventory-presser' ), __( 'Moon Roof', 'inventory-presser' ), __( 'Multi-zone Climate Control', 'inventory-presser' ), __( 'Navigation System', 'inventory-presser' ), __( 'Oversize Off Road Tires', 'inventory-presser' ), __( 'Portable Audio Connection', 'inventory-presser' ), __( 'Power Brakes', 'inventory-presser' ), __( 'Power Lift Gate', 'inventory-presser' ), __( 'Power Locks', 'inventory-presser' ), __( 'Power Seats', 'inventory-presser' ), __( 'Power Steering', 'inventory-presser' ), __( 'Power Windows', 'inventory-presser' ), __( 'Premium Audio', 'inventory-presser' ), __( 'Premium Wheels', 'inventory-presser' ), __( 'Privacy Glass', 'inventory-presser' ), __( 'Quad Seating', 'inventory-presser' ), __( 'Rear Air Bags', 'inventory-presser' ), __( 'Rear Air Conditioning', 'inventory-presser' ), __( 'Rear Defroster', 'inventory-presser' ), __( 'Rear Heat', 'inventory-presser' ), __( 'Refrigerator', 'inventory-presser' ), __( 'Roof Rack', 'inventory-presser' ), __( 'Running Boards', 'inventory-presser' ), __( 'Satellite Radio', 'inventory-presser' ), __( 'Security System', 'inventory-presser' ), __( 'Short Bed', 'inventory-presser' ), __( 'Side Air Bags', 'inventory-presser' ), __( 'Skid Plate(s)', 'inventory-presser' ), __( 'Snow Plow', 'inventory-presser' ), __( 'Spoiler', 'inventory-presser' ), __( 'Sport Package', 'inventory-presser' ), __( 'Step Side Bed', 'inventory-presser' ), __( 'Steering Wheel Controls', 'inventory-presser' ), __( 'Styled Steel Wheels', 'inventory-presser' ), __( 'Sunroof', 'inventory-presser' ), __( 'Supercharger', 'inventory-presser' ), __( 'Tilt Steering Wheel', 'inventory-presser' ), __( 'Tonneau Cover', 'inventory-presser' ), __( 'Topper', 'inventory-presser' ), __( 'Tow Package', 'inventory-presser' ), __( 'Traction Control', 'inventory-presser' ), __( 'Trailer Hitch', 'inventory-presser' ), __( 'Turbo', 'inventory-presser' ), __( 'Two Tone Paint', 'inventory-presser' ), __( 'Wheelchair Access', 'inventory-presser' ), __( 'Wide Tires', 'inventory-presser' ), __( 'Winch', 'inventory-presser' ), __( 'Wire Wheels', 'inventory-presser' ), __( 'Xenon Headlights', 'inventory-presser' ), ) ); // turn the array into an associative array with value false for all $options = array_fill_keys( $options, false ); $options_array = invp_get_the_options( $post->ID ); if ( is_array( $options_array ) ) { foreach ( $options_array as $option ) { $options[ $option ] = true; } } // sort the array by key ksort( $options ); // output a bunch of checkboxes $HTML = '<div class="list-with-columns"><ul class="optional-equipment">'; foreach ( $options as $key => $value ) { // element IDs cannot contain slashes, spaces or parentheses $id = 'option-' . preg_replace( '/\/\(\)/i', '', str_replace( ' ', '_', $key ) ); $HTML .= sprintf( '<li><input type="checkbox" id="%s" name="%s" value="%s"%s><label for="%s">%s</label></li>', $id, 'inventory_presser_options_array[]', $key, checked( true, $value, false ), $id, $key ); } echo $HTML . '</ul></div>'; } /** * meta_box_html_prices * * Creates a meta box to help users manage a vehicles prices in the editor. * * @param WP_Post $post * @param mixed $meta_box * @return void */ function meta_box_html_prices( $post, $meta_box ) { $prices = array( 'price' => 'Price', 'msrp' => 'MSRP', 'down_payment' => 'Down payment', 'payment' => 'Payment', ); echo '<table class="form-table"><tbody>'; foreach ( $prices as $key => $label ) { $meta_key = apply_filters( 'invp_prefix_meta_key', $key ); printf( '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s" onkeypress="return is_number(event)"></td></tr>', $meta_key, $label, $meta_key, INVP::get_meta( $key, $post->ID ) ); } // Payment frequency is a drop-down printf( '<tr><th scope="row"><label for="%s">Payment frequency</label></th>' . '<td><select name="%s"><option></option>', $meta_key, $meta_key ); $frequencies = apply_filters( 'invp_default_payment_frequencies', array( 'Monthly' => 'monthly', 'Weekly' => 'weekly', 'Bi-weekly' => 'biweekly', 'Semi-monthly' => 'semimonthly', ) ); foreach ( $frequencies as $key => $value ) { printf( '<option value="%s"%s>%s</option>', $value, selected( invp_get_the_payment_frequency( $post->ID ), $value, false ), $key ); } echo '</select></td></tr>' . '</tbody></table>'; } /** * meta_box_html_vehicle * * Creates a meta box to help the user manage the bulk of the meta fields * that define a vehicle. * * @param WP_Post $post * @param mixed $meta_box * @return void */ function meta_box_html_vehicle( $post, $meta_box ) { // HTML output for vehicle data meta box $custom = get_post_custom( $post->ID ); $body_style = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'body_style' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'body_style' ) ][0] : '' ); $color = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'color' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'color' ) ][0] : '' ); $engine = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'engine' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'engine' ) ][0] : '' ); $interior_color = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'interior_color' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'interior_color' ) ][0] : '' ); $make = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'make' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'make' ) ][0] : '' ); $model = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'model' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'model' ) ][0] : '' ); $odometer = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'odometer' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'odometer' ) ][0] : '' ); $stock_number = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'stock_number' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'stock_number' ) ][0] : '' ); $trim = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'trim' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'trim' ) ][0] : '' ); $VIN = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'vin' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'vin' ) ][0] : '' ); $year = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'year' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'year' ) ][0] : '' ); $youtube = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'youtube' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'youtube' ) ][0] : '' ); // boat items $beam = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'beam' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'beam' ) ][0] : '' ); $length = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'length' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'length' ) ][0] : '' ); $hull_material = ( isset( $custom[ apply_filters( 'invp_prefix_meta_key', 'hull_material' ) ] ) ? $custom[ apply_filters( 'invp_prefix_meta_key', 'hull_material' ) ][0] : '' ); printf( '<table class="form-table"><tbody>' // VIN . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td>%s</td>' // Stock number . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td>' // Year . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><select name="%s"><option></option>', apply_filters( 'invp_prefix_meta_key', 'vin' ), __( 'VIN', 'inventory-presser' ), apply_filters( 'invp_edit_control_vin', sprintf( '<input type="text" name="%s" maxlength="17" value="%s">', apply_filters( 'invp_prefix_meta_key', 'vin' ), $VIN ) ), apply_filters( 'invp_prefix_meta_key', 'stock_number' ), __( 'Stock number', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'stock_number' ), $stock_number, apply_filters( 'invp_prefix_meta_key', 'year' ), __( 'Year', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'year' ) ); for ( $y = date( 'Y' ) + 2; $y >= 1920; $y-- ) { printf( '<option%s>%s</option>', selected( $y, $year, false ), $y ); } printf( '</select></td></tr>' // Make . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Model . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Trim level . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Engine . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Body style . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" id="%s" value="%s">' . '<select name="%s_hidden" id="%s_hidden">', apply_filters( 'invp_prefix_meta_key', 'make' ), __( 'Make', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'make' ), $make, apply_filters( 'invp_prefix_meta_key', 'model' ), __( 'Model', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'model' ), $model, apply_filters( 'invp_prefix_meta_key', 'trim' ), __( 'Trim', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'trim' ), $trim, apply_filters( 'invp_prefix_meta_key', 'engine' ), __( 'Engine', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'engine' ), $engine, apply_filters( 'invp_prefix_meta_key', 'body_style' ), __( 'Body style', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'body_style' ), apply_filters( 'invp_prefix_meta_key', 'body_style' ), $body_style, apply_filters( 'invp_prefix_meta_key', 'body_style' ), apply_filters( 'invp_prefix_meta_key', 'body_style' ) ); $boat_styles = apply_filters( 'invp_default_boat_styles', array( 'Bass boat', 'Bow Rider', 'Cabin Cruiser', 'Center Console', 'Cuddy Cabin', 'Deck boat', 'Performance', 'Pontoon', ) ); foreach ( $boat_styles as $s ) { printf( '<option%s>%s</option>', selected( $s, $body_style ), $s ); } printf( '</select></td></tr>' // Color . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Interior color . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Odometer . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s">' . ' <span class="invp_odometer_units">%s</span></td></tr>' // YouTube . '<tr><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Beam (boats) . '<tr class="boat-postmeta"><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Length (boats) . '<tr class="boat-postmeta"><th scope="row"><label for="%s">%s</label></th>' . '<td><input type="text" name="%s" value="%s"></td></tr>' // Hull material . '<tr class="boat-postmeta"><th scope="row"><label for="%s">%s</label></th>' . '<td><select name="%s"><option></option>', apply_filters( 'invp_prefix_meta_key', 'color' ), __( 'Color', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'color' ), $color, apply_filters( 'invp_prefix_meta_key', 'interior_color' ), __( 'Interior color', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'interior_color' ), $interior_color, apply_filters( 'invp_prefix_meta_key', 'odometer' ), __( 'Odometer', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'odometer' ), $odometer, apply_filters( 'invp_odometer_word', 'miles' ), apply_filters( 'invp_prefix_meta_key', 'youtube' ), __( 'YouTube video ID', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'youtube' ), $youtube, apply_filters( 'invp_prefix_meta_key', 'beam' ), __( 'Beam', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'beam' ), $beam, apply_filters( 'invp_prefix_meta_key', 'length' ), __( 'Length', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'length' ), $length, apply_filters( 'invp_prefix_meta_key', 'hull_material' ), __( 'Hull material', 'inventory-presser' ), apply_filters( 'invp_prefix_meta_key', 'hull_material' ) ); $hull_materials = apply_filters( 'invp_default_hull_materials', array( 'Aluminum', 'Carbon Fiber', 'Composite', 'Ferro-Cement', 'Fiberglass', 'Hypalon', 'Other', 'PVC', 'Steel', 'Wood', ) ); foreach ( $hull_materials as $m ) { printf( '<option%s>%s</option>', selected( $m, $hull_material, false ), $m ); } echo '</select></tbody></table>'; } /** * move_advanced_meta_boxes * * Rearranges meta boxes on the editor when editing vehicles * * @return void */ function move_advanced_meta_boxes() { global $post, $wp_meta_boxes; $post_type = get_post_type( $post ); if ( INVP::POST_TYPE != $post_type ) { return; } do_meta_boxes( get_current_screen(), 'advanced', $post ); unset( $wp_meta_boxes[ get_post_type( $post ) ]['advanced'] ); } /** * move_tags_meta_box * * Remove and re-add the "Tags" meta box so it ends up at the bottom for our CPT * * @return void */ function move_tags_meta_box() { global $wp_meta_boxes; unset( $wp_meta_boxes[ INVP::POST_TYPE ]['side']['core']['tagsdiv-post_tag'] ); add_meta_box( 'tagsdiv-post_tag', 'Tags', 'post_tags_meta_box', INVP::POST_TYPE, 'side', 'core', array( 'taxonomy' => 'post_tag' ) ); } /** * output_add_media_button_annotation * * AJAX callback to output the content we put near the Add Media button in * the classic editor. * * @return void */ function output_add_media_button_annotation() { // because AJAX echo $this->create_add_media_button_annotation(); wp_die(); } /** * populate_columns_we_added_to_vehicles_table * * Populates the custom columns we added to the posts table in the * dashboard. * * @param string $column_name * @param int $post_id * @return void */ function populate_columns_we_added_to_vehicles_table( $column_name, $post_id ) { $custom_fields = get_post_custom( $post_id ); $val = ( isset( $custom_fields[ $column_name ] ) ? $custom_fields[ $column_name ][0] : '' ); switch ( true ) { case $column_name == apply_filters( 'invp_prefix_meta_key', 'thumbnail' ): echo edit_post_link( get_the_post_thumbnail( $post_id, 'thumbnail' ) ); break; case $column_name == apply_filters( 'invp_prefix_meta_key', 'odometer' ): echo invp_get_the_odometer( '', $post_id ); break; case $column_name == apply_filters( 'invp_prefix_meta_key', 'photo_count' ): echo invp_get_the_photo_count( $post_id ); break; case $column_name == apply_filters( 'invp_prefix_meta_key', 'price' ): echo invp_get_the_price( '-', $post_id ); break; default: echo $val; } } /** * save_vehicle_post_meta * * Saves vehicle attributes into their corresponding post meta fields when * the Save or Update button is clicked in the editor. * * @param int $post_id * @param WP_Post $post * @param bool $is_update * @return void */ function save_vehicle_post_meta( $post_id, $post, $is_update ) { /** * Do not continue if the post is being moved to the trash or if this is * an auto-draft. */ if ( in_array( $post->post_status, array( 'trash', 'auto-draft' ) ) ) { return; } // Abort if autosave or AJAX/quick edit if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { return; } // is this a vehicle? if ( ! empty( $_POST['post_type'] ) && INVP::POST_TYPE != $_POST['post_type'] ) { // no, don't create any meta data for vehicles return; } if ( empty( $_POST ) ) { return; } /** * Tick the last modified date of this vehicle since we're saving changes. * It looks like this: Tue, 06 Sep 2016 09:26:12 -0400 */ $offset = sprintf( '%+03d00', intval( get_option( 'gmt_offset' ) ) ); $timestamp_format = 'D, d M Y h:i:s'; // use post_modified to set last_modified $post_modified = DateTime::createFromFormat( 'Y-m-d H:i:s', $post->post_modified ); $timestamp = $post_modified->format( $timestamp_format ) . ' ' . $offset; update_post_meta( $post_id, apply_filters( 'invp_prefix_meta_key', 'last_modified' ), $timestamp ); /** * If this is not an update or there is no date entered post meta value, * set the date_entered meta value using the post_date */ if ( ! $is_update || empty( INVP::get_meta( 'date_entered', $post_id ) ) ) { // use post_date to set date_entered $post_date = DateTime::createFromFormat( 'Y-m-d H:i:s', $post->post_date ); $timestamp = $post_date->format( $timestamp_format ) . ' ' . $offset; update_post_meta( $post_id, apply_filters( 'invp_prefix_meta_key', 'date_entered' ), $timestamp ); } // Clear this value that is defined by a checkbox update_post_meta( $post_id, apply_filters( 'invp_prefix_meta_key', 'featured' ), '0' ); /** * Loop over the post meta keys we manage and save their values * if we find them coming over as part of the post to save. */ $keys = INVP::keys(); $keys[] = 'options_array'; foreach ( $keys as $key ) { $key = apply_filters( 'invp_prefix_meta_key', $key ); if ( isset( $_POST[ $key ] ) ) { if ( is_array( $_POST[ $key ] ) ) { // delete all meta, this is essentially for the options delete_post_meta( $post->ID, $key ); $options = array(); // collect the options to maintain a CSV field for backwards compatibility foreach ( $this->sanitize_array( $_POST[ $key ] ) as $value ) { add_post_meta( $post->ID, $key, $value ); if ( 'inventory_presser_options_array' == $key ) { $options[] = $value; } } } else { // string data update_post_meta( $post->ID, $key, sanitize_text_field( $_POST[ $key ] ) ); } } } } /** * save_taxonomy_term * * Create a term relationship between a post and a term. Inserts the term * first if it does not exist. * * @param int $post_id * @param string $taxonomy_name * @param string $element_name * @return void */ function save_taxonomy_term( $post_id, $taxonomy_name, $element_name ) { if ( ! isset( $_POST[ $element_name ] ) ) { return; } $term_slug = sanitize_text_field( $_POST[ $element_name ] ); if ( '' == $term_slug ) { // the user is setting the vehicle type to empty string wp_remove_object_terms( $post_id, Inventory_Presser_Taxonomies::get_term_slug( $taxonomy_name, $post_id ), $taxonomy_name ); return; } $term = get_term_by( 'slug', $term_slug, $taxonomy_name ); if ( empty( $term ) || is_wp_error( $term ) ) { // the term does not exist. create it $term_arr = array( 'slug' => sanitize_title( $term_slug ), 'description' => $term_slug, 'name' => $term_slug, ); $id_arr = wp_insert_term( $term_slug, $taxonomy_name, $term_arr ); if ( ! is_wp_error( $id_arr ) ) { $term->term_id = $id_arr['term_id']; } } $set = wp_set_object_terms( $post_id, $term->term_id, $taxonomy_name, false ); if ( is_wp_error( $set ) ) { // There was an error setting the term } } /** * save_vehicle_taxonomy_terms * * Saves custom taxonomy terms when vehicles are saved * * @param int $post_id * @param bool $is_update * @return void */ function save_vehicle_taxonomy_terms( $post_id, $is_update ) { foreach ( $this->taxonomies_slugs_array() as $slug ) { $taxonomy_name = $slug; switch ( $slug ) { case 'style': $slug = 'body_style'; break; case 'model_year': $slug = 'year'; break; } $this->save_taxonomy_term( $post_id, $taxonomy_name, apply_filters( 'invp_prefix_meta_key', $slug ) ); } } /** * sanitize_array * * Sanitizes every member of an array at every level with * sanitize_text_field() * * @param array $arr * @return array */ function sanitize_array( $arr ) { foreach ( $arr as $key => $value ) { if ( is_array( $value ) ) { $arr[ $key ] = $this->sanitize_array( $value ); } else { $arr[ $key ] = sanitize_text_field( $value ); } } return $arr; } /** * taxonomies_slugs_array * * Returns an array of all our taxonomy slugs * * @return array An array of taxonomy slugs */ protected function taxonomies_slugs_array() { $arr = array(); foreach ( Inventory_Presser_Taxonomies::query_vars_array() as $query_var ) { array_push( $arr, str_replace( '-', '_', $query_var ) ); } return $arr; } /** * vehicles_table_columns_orderbys * * Change the dashboard post query to sort based on a custom column we * added. * * @param WP_Query $query * @return void */ function vehicles_table_columns_orderbys( $query ) { if ( ! is_admin() || ! $query->is_main_query() ) { return; } $columns = array( 'color', 'odometer', 'price', 'stock_number', ); $orderby = $query->get( 'orderby' ); foreach ( $columns as $column ) { $meta_key = apply_filters( 'invp_prefix_meta_key', $column ); if ( $orderby == $meta_key ) { $query->set( 'meta_key', $meta_key ); $query->set( 'orderby', 'meta_value' . ( INVP::meta_value_is_number( $meta_key ) ? '_num' : '' ) ); return; } } } }
Expand full source code Collapse full source code View on Github
Methods Methods
- add_columns_to_vehicles_table — add_columns_to_vehicles_table
- add_meta_boxes_to_cpt — add_meta_boxes_to_cpt
- add_vehicles_to_admin_bar — add_vehicles_to_admin_bar
- annotate_add_media_button — annotate_add_media_button
- change_post_updated_messages — change_post_updated_messages
- change_taxonomy_show_ui_attributes — change_taxonomy_show_ui_attributes
- create_add_media_button_annotation — create_add_media_button_annotation
- create_delete_all_post_attachments_button — create_delete_all_post_attachments_button
- delete_all_post_attachments — delete_all_post_attachments
- enable_order_by_attachment_count — enable_order_by_attachment_count
- hooks — hooks
- insert_settings_link — insert_settings_link
- load_scripts — load_scripts
- make_vehicles_table_columns_sortable — make_vehicles_table_columns_sortable
- meta_box_html_featured — meta_box_html_featured
- meta_box_html_options — meta_box_html_options
- meta_box_html_prices — meta_box_html_prices
- meta_box_html_vehicle — meta_box_html_vehicle
- move_advanced_meta_boxes — move_advanced_meta_boxes
- move_tags_meta_box — move_tags_meta_box
- output_add_media_button_annotation — output_add_media_button_annotation
- populate_columns_we_added_to_vehicles_table — populate_columns_we_added_to_vehicles_table
- sanitize_array — sanitize_array
- save_taxonomy_term — save_taxonomy_term
- save_vehicle_post_meta — save_vehicle_post_meta
- save_vehicle_taxonomy_terms — save_vehicle_taxonomy_terms
- taxonomies_slugs_array — taxonomies_slugs_array
- vehicles_table_columns_orderbys — vehicles_table_columns_orderbys
Changelog Changelog
Version | Description |
---|---|
1.3.1 | Introduced. |