mirror of
https://gitlab.com/ArkHost/WP-WHMCS-Pricing.git
synced 2026-09-19 17:37:31 +02:00
first commit
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* Shortcode Handler
|
||||
*
|
||||
* Registers and processes shortcodes
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class WHMCS_Pricing_Shortcodes {
|
||||
|
||||
/**
|
||||
* Single instance
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Translations cache
|
||||
*/
|
||||
private static $translations = null;
|
||||
|
||||
/**
|
||||
* Get instance
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private function __construct() {
|
||||
add_shortcode('whmcs_price', array($this, 'render_price_shortcode'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load translations from JSON file
|
||||
*/
|
||||
private static function load_translations() {
|
||||
if (null !== self::$translations) {
|
||||
return self::$translations;
|
||||
}
|
||||
|
||||
$json_file = WHMCS_PRICING_PLUGIN_DIR . 'languages.json';
|
||||
|
||||
if (file_exists($json_file)) {
|
||||
$json_content = file_get_contents($json_file);
|
||||
self::$translations = json_decode($json_content, true);
|
||||
}
|
||||
|
||||
if (!is_array(self::$translations)) {
|
||||
self::$translations = array();
|
||||
}
|
||||
|
||||
return self::$translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render price shortcode
|
||||
*
|
||||
* @param array $atts Shortcode attributes
|
||||
* @return string HTML output
|
||||
*/
|
||||
public function render_price_shortcode($atts) {
|
||||
// Parse attributes
|
||||
$atts = shortcode_atts(array(
|
||||
'product_id' => '',
|
||||
'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(
|
||||
'<span class="%s" data-product-id="%d" data-cycle="%s">',
|
||||
esc_attr(implode(' ', $classes)),
|
||||
esc_attr($product_id),
|
||||
esc_attr($billing_cycle)
|
||||
);
|
||||
|
||||
$html .= sprintf(
|
||||
'<span class="currency-symbol">%s</span>',
|
||||
esc_html($price_data['symbol'])
|
||||
);
|
||||
|
||||
$html .= sprintf(
|
||||
'<span class="price-amount">%s</span>',
|
||||
esc_html($price_data['formatted'])
|
||||
);
|
||||
|
||||
if (!empty($cycle_text)) {
|
||||
$html .= sprintf(
|
||||
'<span class="billing-cycle">%s</span>',
|
||||
esc_html($cycle_text)
|
||||
);
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
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 '<span class="whmcs-price whmcs-price-error" style="display:none;"></span>';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<span class="whmcs-price whmcs-price-error" style="color: #dc3232; font-style: italic;">[WHMCS Pricing Error: %s]</span>',
|
||||
esc_html($message)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user