From 019d69933b30649ca222e728a87e87402f46821f Mon Sep 17 00:00:00 2001 From: Brian DiChiara <122309362+bd-viget@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:44:50 -0600 Subject: [PATCH] Auction Custom Fields (#73) --- client-mu-plugins/goodbids/README.md | 19 +- .../{ => acf-json}/group_6570c1fa76181.json | 96 ++++++++-- .../src/classes/Auctions/Auctions.php | 170 ++++++++++++++++-- .../goodbids/src/classes/Auctions/Bids.php | 12 +- .../goodbids/src/classes/Plugins/ACF.php | 4 +- 5 files changed, 258 insertions(+), 43 deletions(-) rename client-mu-plugins/goodbids/{ => acf-json}/group_6570c1fa76181.json (58%) diff --git a/client-mu-plugins/goodbids/README.md b/client-mu-plugins/goodbids/README.md index 531dbfbc7..b79a61b86 100644 --- a/client-mu-plugins/goodbids/README.md +++ b/client-mu-plugins/goodbids/README.md @@ -40,15 +40,30 @@ Returns the auction post type slug. `goodbids()->auctions->get_setting( string $setting, int $auction_id )` Returns a setting value for an auction. If `$auction_id` is not provided, the current post ID will be used. -`goodbids()->auctions->get_prize_product_id( int $auction_id )` -Returns the Auction's Prize Product ID. If `$auction_id` is not provided, the current post ID will be used. +`goodbids()->auctions->get_reward_product_id( int $auction_id )` +Returns the Auction's Reward Product ID. If `$auction_id` is not provided, the current post ID will be used. + +`goodbids()->auctions->get_estimated_value( int $auction_id )` +Returns the Auction Reward's Estimated Value. If `$auction_id` is not provided, the current post ID will be used. `goodbids()->auctions->get_start_date_time( int $auction_id )` Returns the Auction's Start Date/Time in MySQL format. If `$auction_id` is not provided, the current post ID will be used. +`goodbids()->auctions->has_started( int $auction_id )` +Checks if the Auction has started. If `$auction_id` is not provided, the current post ID will be used. + `goodbids()->auctions->get_bid_increment( int $auction_id )` Returns the Auction's Bid Increment value. If `$auction_id` is not provided, the current post ID will be used. +`goodbids()->auctions->get_starting_bid( int $auction_id )` +Returns the Auction's Starting Bid value. If `$auction_id` is not provided, the current post ID will be used. + +`goodbids()->auctions->calculate_starting_bid( int $auction_id )` +Returns the Auction's Calculated Starting Bid value, which will use the Bid Increment if the Starting Bid is not set. If `$auction_id` is not provided, the current post ID will be used. + `goodbids()->auctions->get_goal( int $auction_id )` Returns the Auction's Goal value. If `$auction_id` is not provided, the current post ID will be used. +`goodbids()->auctions->get_expected_high_bid( int $auction_id )` +Returns the Auction's Expected High Bid value. If `$auction_id` is not provided, the current post ID will be used. + diff --git a/client-mu-plugins/goodbids/group_6570c1fa76181.json b/client-mu-plugins/goodbids/acf-json/group_6570c1fa76181.json similarity index 58% rename from client-mu-plugins/goodbids/group_6570c1fa76181.json rename to client-mu-plugins/goodbids/acf-json/group_6570c1fa76181.json index 5e0b12f72..805ec0b56 100644 --- a/client-mu-plugins/goodbids/group_6570c1fa76181.json +++ b/client-mu-plugins/goodbids/acf-json/group_6570c1fa76181.json @@ -2,6 +2,24 @@ "key": "group_6570c1fa76181", "title": "Auction Settings", "fields": [ + { + "key": "field_6570c1fb429a8", + "label": "Auction Start", + "name": "auction_start", + "aria-label": "", + "type": "date_time_picker", + "instructions": "", + "required": 1, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "display_format": "m\/d\/Y g:i a", + "return_format": "Y-m-d H:i:s", + "first_day": 0 + }, { "key": "field_657334958904f", "label": "Auction Product", @@ -12,7 +30,7 @@ "required": 1, "conditional_logic": 0, "wrapper": { - "width": "", + "width": "50", "class": "", "id": "" }, @@ -23,7 +41,7 @@ "publish" ], "taxonomy": [ - "product_cat:prizes" + "product_cat:rewards" ], "return_format": "object", "multiple": 0, @@ -33,22 +51,26 @@ "bidirectional_target": [] }, { - "key": "field_6570c1fb429a8", - "label": "Auction Start", - "name": "auction_start", + "key": "field_6579fb39bce91", + "label": "Estimated Value", + "name": "estimated_value", "aria-label": "", - "type": "date_time_picker", + "type": "number", "instructions": "", - "required": 1, + "required": 0, "conditional_logic": 0, "wrapper": { - "width": "", + "width": "50", "class": "", "id": "" }, - "display_format": "m\/d\/Y g:i a", - "return_format": "Y-m-d H:i:s", - "first_day": 0 + "default_value": "", + "min": "", + "max": "", + "placeholder": "", + "step": "", + "prepend": "$", + "append": ".00" }, { "key": "field_657334728904e", @@ -60,7 +82,7 @@ "required": 1, "conditional_logic": 0, "wrapper": { - "width": "", + "width": "50", "class": "", "id": "" }, @@ -72,6 +94,28 @@ "prepend": "$", "append": ".00" }, + { + "key": "field_6579e95a0278a", + "label": "Starting Bid", + "name": "starting_bid", + "aria-label": "", + "type": "number", + "instructions": "If left empty, starting bid will default to Bid Increment value.", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "50", + "class": "", + "id": "" + }, + "default_value": "", + "min": "", + "max": "", + "placeholder": "(Optional)", + "step": "", + "prepend": "$", + "append": ".00" + }, { "key": "field_657334428904d", "label": "Auction Goal", @@ -82,7 +126,29 @@ "required": 0, "conditional_logic": 0, "wrapper": { - "width": "", + "width": "50", + "class": "", + "id": "" + }, + "default_value": "", + "min": "", + "max": "", + "placeholder": "", + "step": "", + "prepend": "$", + "append": ".00" + }, + { + "key": "field_6579fb64bce92", + "label": "Expected High Bid", + "name": "expected_high_bid", + "aria-label": "", + "type": "number", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "50", "class": "", "id": "" }, @@ -108,11 +174,11 @@ "position": "normal", "style": "default", "label_placement": "top", - "instruction_placement": "label", + "instruction_placement": "field", "hide_on_screen": "", "active": true, "description": "", "show_in_rest": 0, - "modified": 1702079254, + "modified": 1702493167, "private": true } diff --git a/client-mu-plugins/goodbids/src/classes/Auctions/Auctions.php b/client-mu-plugins/goodbids/src/classes/Auctions/Auctions.php index bf54b3c92..fb3d529c1 100644 --- a/client-mu-plugins/goodbids/src/classes/Auctions/Auctions.php +++ b/client-mu-plugins/goodbids/src/classes/Auctions/Auctions.php @@ -51,8 +51,11 @@ public function __construct() { // Register Post Type. $this->register_post_type(); - // Init Prizes Category. - $this->init_prizes_category(); + // Init Rewards Category. + $this->init_rewards_category(); + + // Update Bid Product when Auction is updated. + $this->update_bid_product_on_auction_update(); } /** @@ -132,17 +135,17 @@ function () { } /** - * Initialize Prizes Category + * Initialize Rewards Category * * @since 1.0.0 * * @return void */ - private function init_prizes_category() : void { + private function init_rewards_category() : void { add_action( 'init', function () { - $this->get_prizes_category_id(); + $this->get_rewards_category_id(); } ); } @@ -159,18 +162,27 @@ public function get_post_type() : string { } /** - * Retrieve the Prizes category ID, or create it if it doesn't exist. + * Retrieve the Rewards category ID, or create it if it doesn't exist. * * @since 1.0.0 * - * @return int + * @return ?int */ - public function get_prizes_category_id() : int { - $prizes_category = get_term_by( 'slug', 'prizes', 'product_cat' ); - if ( ! $prizes_category ) { - $prizes_category = wp_insert_term( 'Prizes', 'product_cat' ); + public function get_rewards_category_id() : ?int { + $rewards_category = get_term_by( 'slug', 'rewards', 'product_cat' ); + + if ( ! $rewards_category ) { + $rewards_category = wp_insert_term( 'Rewards', 'product_cat' ); + + if ( ! $rewards_category ) { + // TODO: Log error. + return null; + } + + return $rewards_category['term_id']; } - return $prizes_category->term_id; + + return $rewards_category->term_id; } /** @@ -219,7 +231,7 @@ public function set_bid_product_id( int $auction_id, int $bid_product_id ) : voi * @since 1.0.0 * * @param string $meta_key - * @param int|null $auction_id + * @param ?int $auction_id * * @return mixed */ @@ -232,24 +244,37 @@ public function get_setting( string $meta_key, int $auction_id = null ) : mixed } /** - * Get the Auction Prize Product ID. + * Get the Auction Reward Product ID. * * @since 1.0.0 * - * @param int|null $auction_id + * @param ?int $auction_id * * @return int */ - public function get_prize_product_id( int $auction_id = null ) : int { + public function get_reward_product_id( int $auction_id = null ) : int { return intval( $this->get_setting( 'auction_product', $auction_id ) ); } + /** + * Get the Auction Reward Estimated Value. + * + * @since 1.0.0 + * + * @param ?int $auction_id + * + * @return int + */ + public function get_estimated_value( int $auction_id = null ) : int { + return intval( $this->get_setting( 'estimated_value', $auction_id ) ); + } + /** * Get the Auction Start Date/Time * * @since 1.0.0 * - * @param int|null $auction_id + * @param ?int $auction_id * * @return string */ @@ -257,12 +282,30 @@ public function get_start_date_time( int $auction_id = null ) : string { return $this->get_setting( 'auction_start', $auction_id ); } + /** + * Check if an Auction has started. + * + * @since 1.0.0 + * + * @param ?int $auction_id + * + * @return bool + */ + public function has_started( int $auction_id = null ): bool { + $start_date_time = $this->get_start_date_time( $auction_id ); + if ( ! $start_date_time ) { + return false; + } + + return strtotime( $start_date_time ) < time(); + } + /** * Get the Auction Bid Increment amount * * @since 1.0.0 * - * @param int|null $auction_id + * @param ?int $auction_id * * @return int */ @@ -270,16 +313,105 @@ public function get_bid_increment( int $auction_id = null ) : int { return intval( $this->get_setting( 'bid_increment', $auction_id ) ); } + /** + * Get the Auction Starting Bid amount + * + * @since 1.0.0 + * + * @param ?int $auction_id + * + * @return int + */ + public function get_starting_bid( int $auction_id = null ) : int { + return intval( $this->get_setting( 'starting_bid', $auction_id ) ); + } + + /** + * Calculate the Auction Starting Bid amount + * + * @since 1.0.0 + * + * @param ?int $auction_id + * + * @return int + */ + public function calculate_starting_bid( int $auction_id = null ): int { + $starting_bid = $this->get_starting_bid( (int) $auction_id ); + if ( ! $starting_bid ) { + $starting_bid = $this->get_bid_increment( (int) $auction_id ); + } + + return $starting_bid; + } + /** * Get the Auction Goal Amount * * @since 1.0.0 * - * @param int|null $auction_id + * @param ?int $auction_id * * @return int */ public function get_goal( int $auction_id = null ) : int { return intval( $this->get_setting( 'auction_goal', $auction_id ) ); } + + /** + * Get the Auction Expected High Bid Amount + * + * @since 1.0.0 + * + * @param ?int $auction_id + * + * @return int + */ + public function get_expected_high_bid( int $auction_id = null ) : int { + return intval( $this->get_setting( 'expected_high_bid', $auction_id ) ); + } + + /** + * Update the Bid Product when an Auction is updated. + * + * @since 1.0.0 + * + * @return void + */ + private function update_bid_product_on_auction_update(): void { + add_action( + 'save_post', + function ( int $post_id ) { + // Bail if not an Auction and not published. + if ( wp_is_post_revision( $post_id ) || 'publish' !== get_post_status( $post_id ) || self::POST_TYPE !== get_post_type( $post_id ) ) { + return; + } + + // Bail if the Auction doesn't have a Bid product. + if ( ! $this->has_bid_product( $post_id ) ) { + // TODO: Log error. + return; + } + + if ( $this->has_started( $post_id ) ) { + // TODO: Log warning. + return; + } + + // Update the Bid product. + $bid_product_id = goodbids()->auctions->get_bid_product_id( $post_id ); + $bid_product = wc_get_product( $bid_product_id ); + $starting_bid = $this->calculate_starting_bid( $post_id ); + $bid_price = intval( $bid_product->get_price( 'edit' ) ); + + if ( $starting_bid && $bid_price !== $starting_bid ) { + // Update postmeta. + update_post_meta( $bid_product_id, '_price', $starting_bid ); + + // Update current instance. + $bid_product->set_price( $starting_bid ); + $bid_product->save(); + } + } + ); + } } diff --git a/client-mu-plugins/goodbids/src/classes/Auctions/Bids.php b/client-mu-plugins/goodbids/src/classes/Auctions/Bids.php index 35ca447fd..694e783e0 100644 --- a/client-mu-plugins/goodbids/src/classes/Auctions/Bids.php +++ b/client-mu-plugins/goodbids/src/classes/Auctions/Bids.php @@ -38,10 +38,10 @@ public function __construct() { * * @return void */ - private function create_bid_product_for_auction() : void { + private function create_bid_product_for_auction(): void { add_action( 'wp_after_insert_post', - function ( $post_id ) { + function ( $post_id ): void { // Bail if this is a revision. if ( wp_is_post_revision( $post_id ) || 'publish' !== get_post_status( $post_id ) ) { return; @@ -57,10 +57,12 @@ function ( $post_id ) { return; } - $bid_price = goodbids()->auctions->get_bid_increment( (int) $post_id ); + // Set starting bid amount. + $starting_bid = goodbids()->auctions->calculate_starting_bid( (int) $post_id ); // Make sure this meta value has been saved. - if ( ! $bid_price ) { + if ( ! $starting_bid ) { + // TODO: Log error. return; } @@ -76,7 +78,7 @@ function ( $post_id ) { $bid_product = new \WC_Product_Simple(); $bid_product->set_name( $bid_title ); $bid_product->set_slug( sanitize_title( $bid_title ) ); - $bid_product->set_regular_price( $bid_price ); + $bid_product->set_regular_price( $starting_bid ); $bid_product->set_category_ids( [ $this->get_bids_category_id() ] ); $bid_product->set_status( 'publish' ); diff --git a/client-mu-plugins/goodbids/src/classes/Plugins/ACF.php b/client-mu-plugins/goodbids/src/classes/Plugins/ACF.php index a67df4d76..be66743f9 100644 --- a/client-mu-plugins/goodbids/src/classes/Plugins/ACF.php +++ b/client-mu-plugins/goodbids/src/classes/Plugins/ACF.php @@ -66,7 +66,7 @@ private function modify_save_directory() : void { 'acf/settings/save_json', function ( $path ) { if ( defined( 'VIP_GO_APP_ENVIRONMENT' ) && 'local' === VIP_GO_APP_ENVIRONMENT ) { - return GOODBIDS_PLUGIN_PATH; + return GOODBIDS_PLUGIN_PATH . 'acf-json'; } return $path; @@ -76,7 +76,7 @@ function ( $path ) { add_filter( 'acf/settings/load_json', function ( array $paths ) { - $paths[] = GOODBIDS_PLUGIN_PATH; + $paths[] = GOODBIDS_PLUGIN_PATH . 'acf-json'; return $paths; } );