diff --git a/includes/classes/class-cron.php b/includes/classes/class-cron.php index 8858b9a323..e1f84d1597 100644 --- a/includes/classes/class-cron.php +++ b/includes/classes/class-cron.php @@ -98,8 +98,14 @@ public function atbdp_custom_schedule_cron() { */ private function featured_listing_followup() { + if ( directorist_is_force_disabled_featured_listings() ) { + return; + } + if ( directorist_is_monetization_enabled() && directorist_is_featured_listing_enabled() ) { - $featured_days = get_directorist_option( 'featured_listing_time', 30 ); + $featured_days = (int) get_directorist_option( 'featured_listing_time', 30 ); + $orders = directorist_order_repository(); + $current_time = directorist_now()->getTimestamp(); // Define the query $args = [ 'post_type' => ATBDP_POST_TYPE, @@ -120,44 +126,23 @@ private function featured_listing_followup() { // Start the Loop if ( $listings->found_posts ) { foreach ( $listings->posts as $listing ) { - $order = $this->get_order_by_listing( $listing->ID ); - if ( $order ) { - $days = round( abs( strtotime( current_time( 'mysql' ) ) - strtotime( $order[0]->post_date ) ) / 86400 ); - if ( $days > $featured_days ) { - do_action( 'atbdp_listing_featured_to_general', $listing->ID ); - update_post_meta( $listing->ID, '_featured', '' ); - } - } - } - } - } - } + $order = $orders->get_latest_paid_featured_order_by_listing_id( $listing->ID ); - private function get_order_by_listing( $listing_id ) { - $args = [ - 'post_type' => ATBDP_ORDER_POST_TYPE, - 'posts_per_page' => 1, - 'post_status' => 'publish', - 'meta_query' => [ - 'relation' => 'AND', - [ - 'key' => '_listing_id', - 'value' => $listing_id, - ], - [ - 'key' => '_payment_status', - 'value' => 'completed', - ], - ], - ]; + if ( ! $order ) { + continue; + } - $listings = new WP_Query( $args ); + $expiration = ! empty( $order->expires_at ) + ? new \Directorist\Helpers\DateTime( $order->expires_at ) + : ( new \Directorist\Helpers\DateTime( $order->created_at ) )->add_days( $featured_days ); - // Start the Loop - if ( $listings->found_posts ) { - return $listings->posts; + if ( $expiration->getTimestamp() <= $current_time ) { + do_action( 'atbdp_listing_featured_to_general', $listing->ID ); + update_post_meta( $listing->ID, '_featured', '' ); + } + } + } } - return ''; } /** diff --git a/includes/classes/class-featured-listing-checkout.php b/includes/classes/class-featured-listing-checkout.php index e7ae39ef75..9110b22653 100644 --- a/includes/classes/class-featured-listing-checkout.php +++ b/includes/classes/class-featured-listing-checkout.php @@ -13,16 +13,24 @@ class FeaturedListingCheckout { const CHECKOUT_TYPE = 'featured_listing'; - public function __construct() { - add_filter( 'directorist_checkout_types', [$this, 'add_checkout_type'] ); + public function __construct() { add_filter( 'directorist_order_data', [ $this, 'handle_order_data' ] ); - add_action( 'directorist_after_order_update', [$this, 'handle_after_order_update'] ); add_filter( 'directorist_payment_receipt_order_items', [$this, 'handle_payment_receipt_order_items'], 10, 2 ); + + add_action( 'plugins_loaded', [ $this, 'register_hooks' ], 20 ); + } + + public function register_hooks() { + if ( directorist_is_force_disabled_featured_listings() ) { + return; + } + + add_filter( 'directorist_checkout_types', [$this, 'add_checkout_type'] ); + add_action( 'directorist_after_order_update', [$this, 'handle_after_order_update'] ); add_filter( 'directorist_checkout_validation', [$this, 'validate_checkout'], 10, 2 ); add_action( 'directorist_checkout_table', [$this, 'handle_checkout_table'], 10, 4 ); add_filter( 'directorist_checkout_subtotal', [$this, 'handle_checkout_subtotal'], 10, 3 ); add_action( 'directorist_checkout_create_order', [$this, 'handle_checkout_create_order'], 10, 3 ); - add_action( 'directorist_before_order_update', [$this, 'handle_before_order_update'] ); add_filter( 'directorist_checkout_product_name', [$this, 'handle_checkout_product_name'], 10, 2 ); add_filter( 'directorist_ajax_listing_submission_response', [ $this, 'handle_listing_submission_response_data' ], 10, 2 ); add_filter( 'directorist_listing_update_args_after_preview', [ $this, 'handle_listing_status_after_preview' ], 10, 2 ); @@ -125,23 +133,6 @@ public function handle_checkout_create_order( OrderDTO $dto, string $checkout_ty $dto->set_listing_id( $request->get_param( 'listing_id' ) )->set_is_featured_listing( 1 )->set_ref_type( self::CHECKOUT_TYPE )->set_amount( $amount )->set_sub_total( $amount ); } - public function handle_before_order_update( OrderDTO $dto ) { - if ( ! $this->is_featured_order( $dto ) ) { - return; - } - - if ( ! $dto->is_initialized( 'status' ) || $dto->get_status() !== Status::PAID ) { - return; - } - - $order = directorist_get_order_by_id( $dto->get_id() ); - - if ( $order->is_featured_listing && ! $order->expires_at ) { - $featured_days = get_directorist_option( 'featured_listing_time', 30 ); - $dto->set_expires_at( directorist_now()->add_days( $featured_days ) ); - } - } - public function handle_after_order_update( OrderDTO $dto ) { if ( ! $this->is_featured_order( $dto ) ) { return; @@ -156,7 +147,11 @@ public function handle_after_order_update( OrderDTO $dto ) { // Publish the listing if it's pending $listing = get_post( $dto->get_listing_id() ); - + + if ( $listing ) { + $this->updated_listing_expiration( $listing, $dto ); + } + if ( $listing && 'publish' !== $listing->post_status ) { directorist_set_listing_status( $dto->get_listing_id(), 'publish' ); } @@ -165,6 +160,32 @@ public function handle_after_order_update( OrderDTO $dto ) { } } + private function updated_listing_expiration( $listing, OrderDTO $order ) { + if ( get_post_meta( $listing->ID, '_never_expire', true ) ) { + return; + } + + $featured_days = (int) get_directorist_option( 'featured_listing_time', 30 ); + $order_expiration = directorist_now()->add_days( $featured_days ); + + $listing_expiration = get_post_meta( $listing->ID, '_expiry_date', true ); + $listing_expiration_date = $listing_expiration + ? date_create_from_format( 'Y-m-d H:i:s', $listing_expiration, wp_timezone() ) + : false; + + if ( $listing_expiration_date + && $listing_expiration === $listing_expiration_date->format( 'Y-m-d H:i:s' ) + && $listing_expiration_date->getTimestamp() >= $order_expiration->getTimestamp() + ) { + return; + } + + $order->set_expires_at( $order_expiration ); + directorist_order_repository()->silent_update( $order ); + + update_post_meta( $listing->ID, '_expiry_date', $order_expiration->format( 'Y-m-d H:i:s' ) ); + } + public function handle_payment_receipt_order_items( array $order_items, OrderDTO $order ) { if ( ! $this->is_featured_order( $order ) ) { return $order_items; @@ -206,7 +227,7 @@ public function handle_checkout_product_name( string $product_name, OrderDTO $dt } public function is_featured_order( OrderDTO $order_dto ): bool { - if ( ! $order_dto->is_initialized( 'ref_type' ) || ! $order_dto->is_initialized( 'ref' ) || ! $order_dto->is_initialized( 'listing_id' ) ) { + if ( ! $order_dto->is_initialized( 'ref_type' ) || ! $order_dto->is_initialized( 'listing_id' ) ) { return false; } diff --git a/includes/directorist-core-functions.php b/includes/directorist-core-functions.php index 240cf293dd..e2d77dbb53 100644 --- a/includes/directorist-core-functions.php +++ b/includes/directorist-core-functions.php @@ -18,6 +18,13 @@ function directorist_is_guest_submission_enabled() { return (bool) get_directorist_option( 'guest_listings', false ); } +/** + * @return bool + */ +function directorist_is_force_disabled_featured_listings() { + return (bool) apply_filters( 'directorist_is_force_disabled_featured_listings', false ); +} + function directorist_is_featured_listing_enabled( array $context = [] ) { return (bool) apply_filters( 'directorist_is_featured_listing_enabled', get_directorist_option( 'enable_featured_listing' ), $context ); } diff --git a/includes/repositories/order-repository.php b/includes/repositories/order-repository.php index 9a4265dd95..8b8d453c12 100644 --- a/includes/repositories/order-repository.php +++ b/includes/repositories/order-repository.php @@ -89,6 +89,17 @@ public function listing_has_paid_featured_order( int $listing_id ): bool { return $order ? true : false; } + public function get_latest_paid_featured_order_by_listing_id( int $listing_id ) { + return $this->get_query_builder() + ->select( 'd_order.created_at', 'd_order.expires_at' ) + ->where( 'd_order.listing_id', $listing_id ) + ->where( 'd_order.is_featured_listing', 1 ) + ->where( 'd_order.ref_type', 'featured_listing' ) + ->where( 'd_order.status', OrderStatus::PAID ) + ->order_by_desc( 'd_order.id' ) + ->first(); + } + protected function get_orders( Builder $query, Read $dto ) { $query = apply_filters( 'directorist_order_list_query', $query, $dto );