File: /mnt/data/doccure-wp/wp-content/plugins/doccure-elementor/widgets/class-subscription-plans.php
<?php
/**
* Doccure Elementor Subscription Plans widget.
*/
namespace ElementorDoccure\Widgets;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
use Elementor\Group_Control_Background;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class SubscriptionPlans extends Widget_Base {
public function get_name() {
return 'doccure-subscription-plans';
}
public function get_title() {
return __( 'Subscription Plans', 'doccure_elementor' );
}
public function get_icon() {
return 'eicon-price-table';
}
public function get_categories() {
return array( 'doccure' );
}
protected function _register_controls() {
$this->start_controls_section(
'section_content',
array(
'label' => __( 'Content', 'doccure_elementor' ),
)
);
$this->add_control(
'show_heading',
[
'label' => __( 'Show Heading', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'doccure_elementor' ),
'label_off' => __( 'Hide', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->add_control(
'heading_text',
[
'label' => __( 'Heading Text', 'doccure_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Our Pricing Plan', 'doccure_elementor' ),
'condition' => [ 'show_heading' => 'yes' ],
]
);
$this->add_control(
'show_toggle',
[
'label' => __( 'Show Monthly/Yearly Toggle', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'doccure_elementor' ),
'label_off' => __( 'Hide', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
'condition' => [ 'show_heading' => 'yes' ],
]
);
$this->add_control(
'monthly_label',
[
'label' => __( 'Monthly Label', 'doccure_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Monthly', 'doccure_elementor' ),
'condition' => [
'show_heading' => 'yes',
'show_toggle' => 'yes',
],
]
);
$this->add_control(
'yearly_label',
[
'label' => __( 'Yearly Label', 'doccure_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Yearly', 'doccure_elementor' ),
'condition' => [
'show_heading' => 'yes',
'show_toggle' => 'yes',
],
]
);
$this->add_control(
'button_text',
[
'label' => __( 'Button Text', 'doccure_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Choose Plan', 'doccure_elementor' ),
]
);
$this->add_control(
'show_popular_badge',
[
'label' => __( 'Show Popular Badge', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'doccure_elementor' ),
'label_off' => __( 'Hide', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->add_control(
'popular_badge_text',
[
'label' => __( 'Popular Badge Text', 'doccure_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Popular', 'doccure_elementor' ),
'condition' => [ 'show_popular_badge' => 'yes' ],
]
);
$this->add_control(
'show_feature_icons',
[
'label' => __( 'Show Feature Icons', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'doccure_elementor' ),
'label_off' => __( 'Hide', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->add_control(
'show_description',
[
'label' => __( 'Show Plan Description', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Show', 'doccure_elementor' ),
'label_off' => __( 'Hide', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Display plan description under "What\'s included" heading', 'doccure_elementor' ),
]
);
$this->add_control(
'description_source',
[
'label' => __( 'Description Source', 'doccure_elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'post_excerpt' => __( 'Product Short Description', 'doccure_elementor' ),
'post_content' => __( 'Product Full Description', 'doccure_elementor' ),
'custom_field' => __( 'Custom Field', 'doccure_elementor' ),
],
'default' => 'post_excerpt',
'condition' => [ 'show_description' => 'yes' ],
]
);
$this->add_control(
'description_custom_field',
[
'label' => __( 'Custom Field Name', 'doccure_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => 'package_description',
'description' => __( 'Enter the custom field name where description is stored', 'doccure_elementor' ),
'condition' => [
'show_description' => 'yes',
'description_source' => 'custom_field',
],
]
);
$this->add_control(
'description_length',
[
'label' => __( 'Description Length', 'doccure_elementor' ),
'type' => Controls_Manager::NUMBER,
'min' => 0,
'max' => 1000,
'step' => 5,
'default' => 150,
'description' => __( 'Maximum number of characters (0 = no limit)', 'doccure_elementor' ),
'condition' => [ 'show_description' => 'yes' ],
]
);
$this->add_control(
'hide_yes_no_values',
[
'label' => __( 'Hide Yes/No Values', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Yes', 'doccure_elementor' ),
'label_off' => __( 'No', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Hide "Yes/No" values but show numeric values', 'doccure_elementor' ),
]
);
$this->add_control(
'features_limit',
[
'label' => __( 'Features Limit', 'doccure_elementor' ),
'type' => Controls_Manager::NUMBER,
'min' => 0,
'max' => 50,
'step' => 1,
'default' => 0,
'description' => __( '0 = Show all features', 'doccure_elementor' ),
]
);
$this->add_control(
'exclude_features',
[
'label' => __( 'Exclude Features', 'doccure_elementor' ),
'type' => Controls_Manager::TEXTAREA,
'description' => __( 'Enter feature keys to exclude, one per line. Example: dc_services, dc_articles', 'doccure_elementor' ),
'placeholder' => 'dc_services' . PHP_EOL . 'dc_articles',
'rows' => 3,
]
);
$this->add_control(
'show_only_enabled_features',
[
'label' => __( 'Show Only Enabled Features', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Yes', 'doccure_elementor' ),
'label_off' => __( 'No', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'Only show features that are enabled (set to "yes" or "on")', 'doccure_elementor' ),
]
);
$this->add_control(
'product_type_filter',
[
'label' => __( 'Filter by Product Type', 'doccure_elementor' ),
'type' => Controls_Manager::SELECT,
'options' => [
'all' => __( 'All Product Types', 'doccure_elementor' ),
'simple' => __( 'Simple Products Only', 'doccure_elementor' ),
'variable' => __( 'Variable Products Only', 'doccure_elementor' ),
'grouped' => __( 'Grouped Products Only', 'doccure_elementor' ),
'external' => __( 'External/Affiliate Products Only', 'doccure_elementor' ),
'packages' => __( 'packages', 'doccure_elementor' ),
],
'default' => 'simple',
'description' => __( 'Filter which product types to display', 'doccure_elementor' ),
]
);
$this->end_controls_section();
// Manual Icons Section
$this->start_controls_section(
'section_manual_icons',
[
'label' => __( 'Manual Icons', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'use_manual_icons',
[
'label' => __( 'Use Manual Icons', 'doccure_elementor' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => __( 'Yes', 'doccure_elementor' ),
'label_off' => __( 'No', 'doccure_elementor' ),
'return_value' => 'yes',
'default' => 'no',
'description' => __( 'Enable to set custom icons for each pricing card', 'doccure_elementor' ),
]
);
$this->add_control(
'card_1_icon',
[
'label' => __( 'First Card Icon', 'doccure_elementor' ),
'type' => Controls_Manager::MEDIA,
'default' => [
'url' => get_template_directory_uri() . '/assets/images/price-icon1.svg',
],
'condition' => ['use_manual_icons' => 'yes'],
]
);
$this->add_control(
'card_2_icon',
[
'label' => __( 'Second Card Icon', 'doccure_elementor' ),
'type' => Controls_Manager::MEDIA,
'default' => [
'url' => get_template_directory_uri() . '/assets/images/price-icon2.svg',
],
'condition' => ['use_manual_icons' => 'yes'],
]
);
$this->add_control(
'card_3_icon',
[
'label' => __( 'Third Card Icon', 'doccure_elementor' ),
'type' => Controls_Manager::MEDIA,
'default' => [
'url' => get_template_directory_uri() . '/assets/images/price-icon3.svg',
],
'condition' => ['use_manual_icons' => 'yes'],
]
);
$this->add_control(
'icon_size',
[
'label' => __( 'Icon Size', 'doccure_elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 20,
'max' => 100,
],
],
'default' => [
'unit' => 'px',
'size' => 60,
],
'selectors' => [
'{{WRAPPER}} .pricing-icon img' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
],
'condition' => ['use_manual_icons' => 'yes'],
]
);
$this->end_controls_section();
// Description Styles Section
$this->start_controls_section(
'section_style_description',
[
'label' => __( 'Description', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [ 'show_description' => 'yes' ],
]
);
$this->add_control(
'description_color',
[
'label' => __( 'Text Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-description' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'description_typography',
'selector' => '{{WRAPPER}} .pricing-description',
]
);
$this->add_responsive_control(
'description_margin',
[
'label' => __( 'Margin', 'doccure_elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em' ],
'selectors' => [
'{{WRAPPER}} .pricing-description' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'description_padding',
[
'label' => __( 'Padding', 'doccure_elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em' ],
'selectors' => [
'{{WRAPPER}} .pricing-description' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
// Styles
$this->start_controls_section(
'section_style_general',
[
'label' => __( 'General', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'section_background',
[
'label' => __( 'Section Background Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-section' => 'background-color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_heading',
[
'label' => __( 'Heading', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'heading_color',
[
'label' => __( 'Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-inner-header h2' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'heading_typography',
'selector' => '{{WRAPPER}} .pricing-inner-header h2',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_card',
[
'label' => __( 'Card', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'card_background',
[
'label' => __( 'Background Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-card' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'active_card_background',
[
'label' => __( 'Active Card Background', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-card.active' => 'background-color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_title',
[
'label' => __( 'Plan Title', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_color',
[
'label' => __( 'Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-title h4' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} .pricing-title h4',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_price',
[
'label' => __( 'Price', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'price_color',
[
'label' => __( 'Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-amount h2' => 'color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_features',
[
'label' => __( 'Features', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'feature_text_color',
[
'label' => __( 'Text Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-list ul li' => 'color: {{VALUE}};',
],
]
);
$this->add_control(
'feature_icon_color',
[
'label' => __( 'Icon Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .feature-icon' => 'color: {{VALUE}};',
],
'condition' => ['show_feature_icons' => 'yes'],
]
);
$this->add_control(
'feature_icon_size',
[
'label' => __( 'Icon Size', 'doccure_elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 10,
'max' => 30,
],
],
'selectors' => [
'{{WRAPPER}} .feature-icon' => 'font-size: {{SIZE}}{{UNIT}};',
],
'condition' => ['show_feature_icons' => 'yes'],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_button',
[
'label' => __( 'Button', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'button_text_color',
[
'label' => __( 'Text Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-btn .btn' => 'color: {{VALUE}};',
],
]
);
$this->add_control(
'button_background',
[
'label' => __( 'Background Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-btn .btn' => 'background-color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style_custom_icons',
[
'label' => __( 'Custom Icons', 'doccure_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => ['use_manual_icons' => 'yes'],
]
);
$this->add_control(
'icon_background',
[
'label' => __( 'Icon Background Color', 'doccure_elementor' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .pricing-icon' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'icon_border_radius',
[
'label' => __( 'Border Radius', 'doccure_elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px', '%'],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}} .pricing-icon' => 'border-radius: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .pricing-icon img' => 'border-radius: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'icon_padding',
[
'label' => __( 'Padding', 'doccure_elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => ['px', '%'],
'selectors' => [
'{{WRAPPER}} .pricing-icon' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
/**
* Get feature icon based on feature key
*/
private function get_feature_icon($feature_key) {
$icons = [
'dc_services' => 'fas fa-stethoscope',
'dc_articles' => 'fas fa-newspaper',
'dc_awards' => 'fas fa-award',
'dc_memberships' => 'fas fa-users',
'dc_clinics' => 'fas fa-hospital',
'dc_appointments' => 'fas fa-calendar-check',
'dc_whatsappandemail' => 'fas fa-comments',
'dc_prescription' => 'fas fa-file-prescription',
'dc_admission' => 'fas fa-procedures',
'dc_insurance' => 'fas fa-shield-alt',
'dc_chat' => 'fas fa-comment-dots',
'dc_bookings' => 'fas fa-bookmark',
'dc_duration' => 'fas fa-clock',
'dc_featured' => 'fas fa-star',
'dc_featured_duration' => 'fas fa-calendar-star',
];
}
/**
* Get plan description
*/
private function get_plan_description($post_id, $settings) {
if ($settings['show_description'] !== 'yes') {
return '';
}
$description = '';
if ($settings['description_source'] === 'post_excerpt') {
// Get product short description
$product = wc_get_product($post_id);
if ($product) {
$description = $product->get_short_description();
}
} elseif ($settings['description_source'] === 'post_content') {
// Get product full description
$post = get_post($post_id);
if ($post) {
$description = $post->post_content;
}
} elseif ($settings['description_source'] === 'custom_field') {
// Get from custom field
$custom_field = !empty($settings['description_custom_field']) ? $settings['description_custom_field'] : 'package_description';
$description = get_post_meta($post_id, $custom_field, true);
}
// Clean up HTML tags but keep basic formatting
$description = wp_strip_all_tags($description, true);
// Trim description if needed
if (!empty($description) && $settings['description_length'] > 0) {
if (strlen($description) > $settings['description_length']) {
$description = substr($description, 0, $settings['description_length']) . '...';
}
}
return $description;
}
/**
* Check if feature should be displayed based on its value
*/
private function should_display_feature($feature_value, $feature_config, $package_id, $settings) {
$feature_type = isset($feature_config['type']) ? $feature_config['type'] : '';
$options = isset($feature_config['options']) ? $feature_config['options'] : [];
// If "Show Only Enabled Features" is enabled
if ($settings['show_only_enabled_features'] === 'yes') {
// For select type with yes/no options
if ($feature_type === 'select' && !empty($options)) {
// Check if the value means "enabled"
if (isset($options[$feature_value])) {
$display_value = $options[$feature_value];
// Check if the value indicates it's enabled
if (in_array(strtolower($display_value), ['yes', 'on', 'enabled', 'active', 'true', '1'])) {
return true;
} elseif (in_array(strtolower($display_value), ['no', 'off', 'disabled', 'inactive', 'false', '0'])) {
return false;
}
}
}
// For boolean-like values
if (in_array(strtolower($feature_value), ['yes', 'on', 'enabled', 'active', 'true', '1'])) {
return true;
} elseif (in_array(strtolower($feature_value), ['no', 'off', 'disabled', 'inactive', 'false', '0', ''])) {
return false;
}
// For number type, show if value is not empty and not 0 (unless 0 means unlimited)
if ($feature_type === 'number') {
if ($feature_value === '0' || $feature_value === 0) {
return true; // Show "Unlimited"
} elseif (!empty($feature_value)) {
return true;
} else {
return false;
}
}
// For other types, show if value is not empty
return !empty($feature_value);
}
// If "Show Only Enabled Features" is disabled, show all features
return true;
}
/**
* Check if feature value should be displayed
*/
private function should_display_feature_value($feature_value, $feature_config, $settings) {
$feature_type = isset($feature_config['type']) ? $feature_config['type'] : '';
// If "Hide Yes/No Values" is enabled
if ($settings['hide_yes_no_values'] === 'yes') {
// Check if this is a boolean value (yes/no)
if (in_array(strtolower($feature_value), ['yes', 'no', 'on', 'off', '1', '0', 'true', 'false'])) {
return false; // Don't show yes/no values
}
// For select type with yes/no options
if ($feature_type === 'select') {
$options = isset($feature_config['options']) ? $feature_config['options'] : [];
if (isset($options[$feature_value])) {
$display_value = $options[$feature_value];
if (in_array(strtolower($display_value), ['yes', 'no', 'on', 'off'])) {
return false; // Don't show yes/no values
}
}
}
}
// For number type, always show the value (including "Unlimited" for 0)
if ($feature_type === 'number') {
return true;
}
// For other types, show the value
return true;
}
/**
* Get manual icon URL based on card position
*/
private function get_manual_icon_url($card_position, $settings) {
switch ($card_position) {
case 1:
return !empty($settings['card_1_icon']['url']) ? $settings['card_1_icon']['url'] : '';
case 2:
return !empty($settings['card_2_icon']['url']) ? $settings['card_2_icon']['url'] : '';
case 3:
return !empty($settings['card_3_icon']['url']) ? $settings['card_3_icon']['url'] : '';
default:
return '';
}
}
/**
* Render feature value for display
*/
private function render_feature_value_display($feature_value, $feature_config) {
$feature_type = isset($feature_config['type']) ? $feature_config['type'] : '';
$options = isset($feature_config['options']) ? $feature_config['options'] : [];
if ($feature_type === 'select' && !empty($options)) {
// Handle select type with options
if (isset($options[$feature_value])) {
return $options[$feature_value];
} elseif (is_array($options) && in_array($feature_value, array_values($options))) {
return $feature_value;
}
} elseif ($feature_type === 'number') {
// Handle number type
if ($feature_value === '0' || $feature_value === 0) {
return esc_html__('Unlimited', 'doccure_elementor');
} elseif (!empty($feature_value)) {
return $feature_value;
} else {
return '0';
}
}
// Default handling for boolean values
if ($feature_value === 'yes' || $feature_value === 'on' || $feature_value === '1') {
return esc_html__('Yes', 'doccure_elementor');
} elseif ($feature_value === 'no' || $feature_value === 'off' || $feature_value === '0' || empty($feature_value)) {
return esc_html__('No', 'doccure_elementor');
}
return $feature_value;
}
protected function render() {
$settings = $this->get_settings_for_display();
// Get excluded features
$excluded_features = [];
if (!empty($settings['exclude_features'])) {
$excluded_features = array_map('trim', explode("\n", $settings['exclude_features']));
}
global $current_user, $doccure_options;
$user_identity = isset($current_user->ID) ? $current_user->ID : 0;
$linked_profile = function_exists('doccure_get_linked_profile_id') ? doccure_get_linked_profile_id($user_identity) : 0;
$icon = 'lnr lnr-hourglass';
$expiry_string = function_exists('doccure_get_subscription_metadata') ? doccure_get_subscription_metadata('subscription_package_string', intval($user_identity)) : false;
$package_expiry_img = !empty($doccure_options['package_expiry']['url']) ? $doccure_options['package_expiry']['url'] : '';
$formatted_date = '';
if ($expiry_string !== false) {
$formatted_date = date('Y, n, d, H, i, s', strtotime('-1 month', intval($expiry_string)));
}
$currency_symbol = function_exists('doccure_get_current_currency') ? doccure_get_current_currency() : array('symbol' => get_woocommerce_currency_symbol());
$pakeges_features = function_exists('doccure_get_pakages_features') ? doccure_get_pakages_features() : array();
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
);
// Filter by package_type meta exists
$meta_query_args = array(
'relation' => 'AND',
array(
'key' => 'package_type',
'compare' => 'EXISTS',
)
);
// Filter by product type if not "all"
if ($settings['product_type_filter'] !== 'all') {
$tax_query = array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => $settings['product_type_filter'],
),
);
$args['tax_query'] = $tax_query;
}
$args['meta_query'] = $meta_query_args;
$loop = new \WP_Query($args);
?>
<section class="pricing-section">
<div class="container">
<?php if ($settings['show_heading'] === 'yes') : ?>
<div class="row">
<div class="col-md-12 text-center">
<div class="section-inner-header pricing-inner-header">
<h2><?php echo esc_html(!empty($settings['heading_text']) ? $settings['heading_text'] : __('Our Pricing Plan', 'doccure_elementor')); ?></h2>
<?php if ($settings['show_toggle'] === 'yes') : ?>
<div class="plan-choose-info">
<label class="monthly-plan"><?php echo esc_html($settings['monthly_label']); ?></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" checked>
</div>
<label class="yearly-plan"><?php echo esc_html($settings['yearly_label']); ?></label>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (class_exists('WooCommerce')) : ?>
<?php if ($loop->have_posts()) : ?>
<div class="row align-items-center justify-content-center">
<?php
$count = 0;
while ($loop->have_posts()) : $loop->the_post();
global $product;
if (!$product) continue;
$post_id = intval($product->get_id());
// Check if this is a simple product (if filtering by simple)
if ($settings['product_type_filter'] === 'simple') {
$product_type = $product->get_type();
if ($product_type !== 'simple') {
continue; // Skip if not a simple product
}
}
$count++;
$title = get_the_title();
$duration_type = get_post_meta($post_id, 'dc_duration', true);
$duration_title = function_exists('doccure_get_duration_types') ? doccure_get_duration_types($duration_type, 'title') : '';
$package_type = get_post_meta($post_id, 'package_type', true);
// Determine if this is the active/popular card
$is_active = false;
if ($settings['show_popular_badge'] === 'yes' && $count == 2) {
$is_active = true;
}
// Get package subtitle
$package_subtitle = get_post_meta($post_id, 'package_subtitle', true);
if (empty($package_subtitle)) {
switch($package_type) {
case 'doctors':
$package_subtitle = __('For Doctors', 'doccure_elementor');
break;
case 'hospitals':
$package_subtitle = __('For Hospitals', 'doccure_elementor');
break;
case 'regular':
default:
$package_subtitle = __('For Individuals', 'doccure_elementor');
break;
}
}
// Get plan description
$plan_description = $this->get_plan_description($post_id, $settings);
// Determine column class based on number of posts
$total_posts = $loop->post_count;
$col_class = 'col-lg-4 col-md-6';
if ($total_posts === 1) {
$col_class = 'col-lg-12';
} elseif ($total_posts === 2) {
$col_class = 'col-lg-6 col-md-6';
} elseif ($total_posts >= 4) {
$col_class = 'col-lg-3 col-md-6';
}
// Get icon URL
$icon_url = '';
if ($settings['use_manual_icons'] === 'yes') {
// Use manual icons
$icon_url = $this->get_manual_icon_url($count, $settings);
} else {
// Use product meta or default icons
$icon_url = get_post_meta($post_id, 'package_icon', true);
if (empty($icon_url)) {
$icon_number = ($count % 3) + 1;
$correct_path = get_template_directory_uri() . '/assets/images/price-icon' . $icon_number . '.svg';
$correct_file_path = get_template_directory() . '/assets/images/price-icon' . $icon_number . '.svg';
if (file_exists($correct_file_path)) {
$icon_url = $correct_path;
} else {
// Fallback SVG
$icon_svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 60 60">
<circle cx="30" cy="30" r="28" fill="' . ($is_active ? '#4CAF50' : '#2196F3') . '" stroke="#fff" stroke-width="2"/>
<text x="30" y="38" text-anchor="middle" fill="#fff" font-size="20" font-weight="bold">' . $count . '</text>
</svg>';
$icon_url = 'data:image/svg+xml;base64,' . base64_encode($icon_svg);
}
}
}
// Fallback if manual icon is empty
if (empty($icon_url) && $settings['use_manual_icons'] === 'yes') {
$icon_number = ($count % 3) + 1;
$correct_path = get_template_directory_uri() . '/assets/images/price-icon' . $icon_number . '.svg';
$correct_file_path = get_template_directory() . '/assets/images/price-icon' . $icon_number . '.svg';
if (file_exists($correct_file_path)) {
$icon_url = $correct_path;
}
}
?>
<div class="<?php echo esc_attr($col_class); ?>">
<div class="card pricing-card w-100 <?php echo $is_active ? 'active' : ''; ?>">
<div class="card-body">
<div class="pricing-header">
<div class="pricing-header-info">
<div class="pricing-icon">
<span>
<?php if (!empty($icon_url)) : ?>
<img src="<?php echo esc_url($icon_url); ?>" alt="<?php echo esc_attr($title); ?>">
<?php else : ?>
<div style="width: 60px; height: 60px; background: #f0f0f0; border-radius: 50%; display: flex; align-items: center; justify-content: center;">
<span style="font-size: 20px; font-weight: bold;"><?php echo esc_html($count); ?></span>
</div>
<?php endif; ?>
</span>
</div>
<div class="pricing-title">
<p><?php echo esc_html($package_subtitle); ?></p>
<h4><?php echo esc_html($title); ?></h4>
</div>
</div>
<?php if ($is_active && !empty($settings['popular_badge_text'])) : ?>
<div>
<span class="badge"><?php echo esc_html($settings['popular_badge_text']); ?></span>
</div>
<?php endif; ?>
</div>
<div class="pricing-info">
<div class="pricing-amount">
<h2><?php echo esc_html($currency_symbol['symbol']); ?><?php echo esc_html($product->get_price()); ?> <span>/<?php echo esc_html($duration_title); ?></span></h2>
<h6><?php echo esc_html__('What\'s included', 'doccure_elementor'); ?></h6>
<?php if ($settings['show_description'] === 'yes' && !empty($plan_description)) : ?>
<div class="pricing-description">
<?php echo wp_kses_post($plan_description); ?>
</div>
<?php endif; ?>
</div>
<div class="pricing-list">
<ul>
<?php
if (!empty($pakeges_features)) {
$feature_count = 0;
foreach ($pakeges_features as $key => $vals) {
// Skip excluded features
if (in_array($key, $excluded_features)) {
continue;
}
$feature_title = isset($vals['title']) ? $vals['title'] : '';
if ($feature_title === '') continue;
$val_user_type = isset($vals['user_type']) ? $vals['user_type'] : '';
$applies = ($val_user_type === 'common' || (!empty($package_type) && $val_user_type === $package_type));
if ($applies) {
$feature_value = get_post_meta($post_id, $key, true);
// Check if feature should be displayed based on its value
if (!$this->should_display_feature($feature_value, $vals, $post_id, $settings)) {
continue;
}
// Check if we should limit features
if ($settings['features_limit'] > 0 && $feature_count >= $settings['features_limit']) {
break;
}
$feature_count++;
// Check if we should show the value
$show_value = $this->should_display_feature_value($feature_value, $vals, $settings);
$display_value = $this->render_feature_value_display($feature_value, $vals);
// For number type with 0 value, show "Unlimited"
if (isset($vals['type']) && $vals['type'] === 'number' && ($feature_value === '0' || $feature_value === 0)) {
?>
<li>
<?php if ($settings['show_feature_icons'] === 'yes') : ?>
<i class="feature-icon <?php echo esc_attr($this->get_feature_icon($key)); ?>"></i>
<?php endif; ?>
<span class="feature-title"><?php echo esc_html($feature_title); ?>: </span>
<span class="feature-value"><?php echo esc_html__('Unlimited', 'doccure_elementor'); ?></span>
</li>
<?php
} elseif ($show_value && !empty($display_value)) {
// Show label with value
?>
<li>
<?php if ($settings['show_feature_icons'] === 'yes') : ?>
<i class="feature-icon <?php echo esc_attr($this->get_feature_icon($key)); ?>"></i>
<?php endif; ?>
<span class="feature-title"><?php echo esc_html($feature_title); ?>: </span>
<span class="feature-value"><?php echo esc_html($display_value); ?></span>
</li>
<?php
} else {
// Show only the label (no value)
?>
<li>
<?php if ($settings['show_feature_icons'] === 'yes') : ?>
<i class="feature-icon <?php echo esc_attr($this->get_feature_icon($key)); ?>"></i>
<?php endif; ?>
<span class="feature-title"><?php echo esc_html($feature_title); ?></span>
</li>
<?php
}
}
}
// Show "and more" if features are limited
if ($settings['features_limit'] > 0 && $feature_count >= $settings['features_limit']) {
echo '<li class="feature-more">' . esc_html__('And more...', 'doccure_elementor') . '</li>';
}
// Show message if no features are enabled
if ($feature_count === 0 && $settings['show_only_enabled_features'] === 'yes') {
echo '<li class="no-features">' . esc_html__('No features enabled for this package', 'doccure_elementor') . '</li>';
}
}
?>
</ul>
</div>
<div class="pricing-btn <?php echo $title; ?>">
<a href="javascript:;" class="btn btn-primary renew-package" data-key="<?php echo intval($post_id); ?>" role="button"><?php echo esc_html($settings['button_text']); ?></a>
</div>
</div>
</div>
</div>
</div>
<?php endwhile; ?>
<?php if ($count === 0) : ?>
<div class="col-12">
<div class="alert alert-info text-center">
<?php
$message = '';
if ($settings['product_type_filter'] === 'simple') {
$message = __('No simple package products found. Please create simple products with package_type meta field.', 'doccure_elementor');
} else {
$message = __('No package products found. Please create products with package_type meta field.', 'doccure_elementor');
}
echo esc_html($message);
?>
</div>
</div>
<?php endif; ?>
</div>
<?php if ($count > 0) : ?>
<script>
(function($){
if (typeof window.doccureRenewBind === 'undefined') {
window.doccureRenewBind = true;
$(document).on('click', '.renew-package', function(e){
e.preventDefault();
var id = $(this).data('key');
if(!id){ return; }
var $btn = $(this);
$btn.prop('disabled', true).addClass('disabled');
$.post('<?php echo esc_url(admin_url('admin-ajax.php')); ?>', {
action: 'doccure_update_cart',
security: '<?php echo esc_js(wp_create_nonce('ajax_nonce')); ?>',
id: id
}).done(function(res){
try {
if (typeof res === 'string') { res = JSON.parse(res); }
} catch(e) {}
if (res && res.type === 'success' && res.checkout_url) {
window.location.href = res.checkout_url;
} else if (res && res.message) {
alert(res.message);
} else {
alert('<?php echo esc_js(__('Unexpected error. Please try again.', 'doccure_elementor')); ?>');
}
}).fail(function(){
alert('<?php echo esc_js(__('Network error. Please try again.', 'doccure_elementor')); ?>');
}).always(function(){
$btn.prop('disabled', false).removeClass('disabled');
});
});
}
})(jQuery);
</script>
<?php endif; ?>
<?php else : ?>
<?php
$message = '';
if ($settings['product_type_filter'] === 'simple') {
$message = __('No simple package products found. Please create simple products with package_type meta field.', 'doccure_elementor');
} else {
$message = __('No package products found. Please create products with package_type meta field.', 'doccure_elementor');
}
do_action('doccure_empty_records_html', '', $message, true);
?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
<?php do_action('doccure_empty_records_html', '', esc_html__('Please install woocommerce.', 'doccure_elementor'), true); ?>
<?php endif; ?>
</div>
</section>
<?php
}
}