product = $product; } public function get_trial(): ?string { if ( $this->has_trial() ) { $product_trial_per = $this->get_trial_timing_per(); return $product_trial_per . ' ' . Helper::get_typos( $product_trial_per, $this->get_trial_timing_option() ); } return null; } public function has_trial(): bool { $trial_timing_per = $this->get_trial_timing_per(); $product_id = $this->product->get_id(); return ( $trial_timing_per > 0 ) && Helper::check_trial( $product_id ); } public function get_button_label() { return $this->product->get_meta( '_subscrpt_cart_btn_label' ); } /** * Magic method to call methods from the WC_Product object. * * @param string $name The method name. * @param array $arguments The method arguments. * @return mixed The result of the called method. * @uses \WC_Product::__call() */ public function __call( $name, $arguments ) { return $this->product->{$name}( ...$arguments ); } public function get_timing_per(): int { return 1; } public function get_timing_option(): string { return Helper::get_typos( $this->get_timing_per(), $this->product->get_meta( '_subscrpt_timing_option' ) ); } public function get_limit() { return $this->product->get_meta( '_subscrpt_limit' ); } public function get_renewal_limit() { return $this->product->get_meta( '_subscrpt_max_no_payment' ); } public function get_max_no_payment() { return $this->product->get_meta( '_subscrpt_max_no_payment' ); } public function is_enabled(): bool { if ( empty( $this->product->get_meta( '_subscrpt_enabled' ) ) ) { return false; } // Once plan-connected, a product is a subscription only while it still has // a plan — it never falls back to the legacy terms after a detach. if ( 'yes' === $this->product->get_meta( '_subscrpt_plan_connected_before' ) && function_exists( 'subscrpt_product_has_plan' ) ) { $parent = $this->product->get_parent_id(); $has_plan = $parent ? subscrpt_product_has_plan( $parent, $this->product->get_id() ) : subscrpt_product_has_plan( $this->product->get_id() ); if ( ! $has_plan ) { return false; } } return true; } public function get_trial_timing_per(): int { return (int) ( $this->product->get_meta( '_subscrpt_trial_timing_per' ) ?? 1 ); } public function get_trial_timing_option() { return $this->product->get_meta( '_subscrpt_trial_timing_option' ); } public function get_signup_fee(): float { return 0; } /** * Get the payment type (recurring or split_payment). * * @return string Payment type. */ public function get_payment_type(): string { return $this->product->get_meta( '_subscrpt_payment_type' ) ?: 'recurring'; } /** * Check if product uses split payment type. * * @return bool True if split payment, false otherwise. */ public function is_split_payment(): bool { return 'split_payment' === $this->get_payment_type(); } /** * Get access ends timing for split payments. * * @return string Access ends timing option. */ public function get_access_ends_timing(): string { return $this->product->get_meta( '_subscrpt_access_ends_timing' ) ?: 'after_full_duration'; } /** * Get custom access duration time. * * @return int Custom access duration time. */ public function get_custom_access_duration_time(): int { return (int) ( $this->product->get_meta( '_subscrpt_custom_access_duration_time' ) ?: 1 ); } /** * Get custom access duration type. * * @return string Custom access duration type (days, weeks, months, years). */ public function get_custom_access_duration_type(): string { return $this->product->get_meta( '_subscrpt_custom_access_duration_type' ) ?: 'months'; } /** * Check if product has custom access duration. * * @return bool True if custom duration, false otherwise. */ public function has_custom_access_duration(): bool { return 'custom_duration' === $this->get_access_ends_timing(); } }