'',
'billing_cycle' => 'monthly',
'currency' => '',
'format' => 'default',
'show_cycle' => 'true',
'class' => '',
'lang' => 'english',
'language' => '' // Support both lang and language
), $atts, 'whmcs_price');
// Validate product ID
if (empty($atts['product_id'])) {
return $this->render_error(__('Product ID is required', 'whmcs-pricing'));
}
// Sanitize attributes
$product_id = absint($atts['product_id']);
$billing_cycle = sanitize_text_field($atts['billing_cycle']);
$currency = !empty($atts['currency']) ? sanitize_text_field($atts['currency']) : '';
$format = sanitize_text_field($atts['format']);
$show_cycle = filter_var($atts['show_cycle'], FILTER_VALIDATE_BOOLEAN);
$custom_class = sanitize_html_class($atts['class']);
// Support both 'lang' and 'language' parameters
$lang = !empty($atts['language']) ? sanitize_text_field($atts['language']) : sanitize_text_field($atts['lang']);
// Get price from API
$price_data = WHMCS_Pricing_API::get_price($product_id, array(
'billing_cycle' => $billing_cycle,
'currency' => $currency,
'format' => $format
));
// Check for errors
if (is_wp_error($price_data)) {
return $this->render_error($price_data->get_error_message());
}
// Render the price
return $this->render_price_html($price_data, $billing_cycle, $product_id, $show_cycle, $custom_class, $lang);
}
/**
* Render price HTML
*
* @param array $price_data Price data from API
* @param string $billing_cycle Billing cycle
* @param int $product_id Product ID
* @param bool $show_cycle Whether to show billing cycle
* @param string $custom_class Custom CSS class
* @param string $lang Language code
* @return string HTML output
*/
private function render_price_html($price_data, $billing_cycle, $product_id, $show_cycle, $custom_class, $lang = 'english') {
$classes = array('whmcs-price');
if (!empty($custom_class)) {
$classes[] = $custom_class;
}
$cycle_text = $show_cycle ? $this->get_cycle_text($billing_cycle, $lang) : '';
$html = sprintf(
'',
esc_attr(implode(' ', $classes)),
esc_attr($product_id),
esc_attr($billing_cycle)
);
$html .= sprintf(
'%s',
esc_html($price_data['symbol'])
);
$html .= sprintf(
'%s',
esc_html($price_data['formatted'])
);
if (!empty($cycle_text)) {
$html .= sprintf(
'%s',
esc_html($cycle_text)
);
}
$html .= '';
return $html;
}
/**
* Get billing cycle text
*
* @param string $cycle Billing cycle
* @param string $lang Language code
* @return string Human-readable cycle text
*/
private function get_cycle_text($cycle, $lang = 'english') {
$cycle = strtolower($cycle);
// Load translations
$translations = self::load_translations();
// Check if language exists, fallback to English
if (!isset($translations[$lang])) {
$lang = 'english';
}
// Get translated text
if (isset($translations[$lang][$cycle])) {
return ' ' . $translations[$lang][$cycle];
}
// Final fallback to English defaults
$defaults = array(
'monthly' => 'per month',
'quarterly' => 'per quarter',
'semiannually' => 'per 6 months',
'annually' => 'per year',
'biennially' => 'per 2 years',
'triennially' => 'per 3 years'
);
return isset($defaults[$cycle]) ? ' ' . $defaults[$cycle] : '';
}
/**
* Render error message
*
* @param string $message Error message
* @return string HTML output
*/
private function render_error($message) {
// Only show errors to administrators
if (!current_user_can('manage_options')) {
return '';
}
return sprintf(
'[WHMCS Pricing Error: %s]',
esc_html($message)
);
}
}