ifnex/03_WordPress/wp-content/plugins/ifnex-bridge/ifnex-bridge.php
Kazem Alghasi b9ede16613 refactor(core): harden production environment and fix discount logic
Implement critical security hardening and resolve a P0 bug in the
discount code consumption flow. This update transitions the system
from a development-heavy configuration to a production-ready state.

Key changes:
- Fix P0 bug where `consumeDiscountCode()` was missing, breaking order
  registration; replaced with a robust `DiscountCodeService` using
  `discount_code_usages` for audit trails and idempotency.
- Implement strict production guards for the Zarinpal payment gateway
  to prevent accidental mock processing in live environments.
- Refactor WordPress bridge asset management to use `filemtime` based
  versioning instead of `time()` to prevent unnecessary cache busting.
- Remove debug-only hacks (`opcache_reset`, `header` cache control)
  from the WordPress plugin.
- Enhance file upload security by enforcing strict `mimetypes` validation.
- Update `.gitignore` to exclude sensitive WordPress configuration
  files and local PHPUnit caches.
- Add comprehensive documentation for production deployment, including
  security checklists and key rotation procedures.
- Update test suite to reflect new architecture and ensure 100%
  coverage of the discount service.
2026-10-31 19:18:58 +03:30

118 lines
6.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Plugin Name: IFNEX Logistics Bridge
* Description: اتصال فرانت‌اند سایت ایف‌نکس به API لاراول
* Version: 1.0
* Author: VernaSoft group (Kazem Alghasi)
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// ─── نسخهٔ پلاگین + cache-busting سالم assetها (سخت‌سازی Production) ───
// قبلاً اینجا opcache_reset() و header('Cache-Control: no-store') بود که فقط برای دیباگ
// لوکال مناسب است و در Production باعث header error و شکستن کش CDN/مرورگر می‌شد — حذف شد.
if ( ! defined( 'IFNEX_BRIDGE_VERSION' ) ) {
define( 'IFNEX_BRIDGE_VERSION', '2.1.0' );
}
/**
* نسخهٔ asset بر اساس آخرین زمان تغییر فایل.
* کش مرورگر فقط وقتی فایل واقعاً عوض شود باطل می‌شود — جایگزین استاندارد time().
*/
if ( ! function_exists( 'ifnex_asset_version' ) ) {
function ifnex_asset_version( string $relative_path ): string {
$file = plugin_dir_path( __FILE__ ) . ltrim( $relative_path, '/' );
$mtime = file_exists( $file ) ? (string) filemtime( $file ) : '0';
return IFNEX_BRIDGE_VERSION . '.' . $mtime;
}
}
// لود کردن فایل‌های پلاگین
require_once plugin_dir_path( __FILE__ ) . 'includes/api-client.php';
require_once plugin_dir_path( __FILE__ ) . 'includes/user-bridge.php';
require_once plugin_dir_path( __FILE__ ) . 'includes/shortcodes.php';
require_once plugin_dir_path( __FILE__ ) . 'includes/tracking-form.php';
// لود کردن استایل‌های و اسکریپت‌های پلاگین
add_action('wp_enqueue_scripts', 'ifnex_enqueue_scripts');
function ifnex_enqueue_scripts() {
global $post;
if (is_a($post, 'WP_Post') &&
(has_shortcode($post->post_content, 'ifnex_tracking_form') ||
has_shortcode($post->post_content, 'ifnex_wallet_balance') ||
has_shortcode($post->post_content, 'ifnex_transactions') ||
has_shortcode($post->post_content, 'ifnex_tracking_status') ||
has_shortcode($post->post_content, 'ifnex_order_form') ||
has_shortcode($post->post_content, 'ifnex_user_profile') ||
has_shortcode($post->post_content, 'ifnex_orders_list') ||
has_shortcode($post->post_content, 'ifnex_order_detail') ||
has_shortcode($post->post_content, 'ifnex_order_payment') ||
has_shortcode($post->post_content, 'ifnex_customer_dashboard'))) {
wp_enqueue_style('ifnex-bridge-css', plugin_dir_url(__FILE__) . 'assets/css/ifnex-bridge.css', array('ifnex-main'), ifnex_asset_version('assets/css/ifnex-bridge.css'));
// SweetAlert2 — پاپ‌آپ خطاها (فاز ۳.۸) — باندل محلی، بدون وابستگی به CDN
wp_enqueue_script('sweetalert2', plugin_dir_url(__FILE__) . 'assets/js/sweetalert2.all.min.js', array(), '11.14.5', true);
wp_enqueue_script('ifnex-order-form-js', plugin_dir_url(__FILE__) . 'assets/js/ifnex-order-form.js', array('jquery', 'sweetalert2'), ifnex_asset_version('assets/js/ifnex-order-form.js'), true);
}
}
// اضافه کردن لینک به منوی پیشخوان وردپرس
add_action( 'admin_menu', 'ifnex_plugin_setup_menu' );
function ifnex_plugin_setup_menu() {
add_menu_page( 'تنظیمات IFNEX', 'IFNEX', 'manage_options', 'ifnex-settings', 'ifnex_settings_page_html', 'dashicons-location-alt', 30 );
}
function ifnex_settings_page_html() {
if (isset($_POST['ifnex_api_url']) && check_admin_referer('ifnex_settings_save')) {
update_option('ifnex_api_url', sanitize_url($_POST['ifnex_api_url']));
update_option('ifnex_api_key', sanitize_text_field($_POST['ifnex_api_key']));
update_option('ifnex_bridge_api_key', sanitize_text_field($_POST['ifnex_bridge_api_key'] ?? ''));
echo '<div class="notice notice-success"><p>تنظیمات ذخیره شد.</p></div>';
}
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
$api_key = get_option('ifnex_api_key', '');
$bridge_api_key = get_option('ifnex_bridge_api_key', '');
?>
<div class="wrap">
<h1>تنظیمات IFNEX Logistics Bridge</h1>
<form method="post">
<?php wp_nonce_field('ifnex_settings_save'); ?>
<table class="form-table">
<tr>
<th scope="row"><label for="ifnex_api_url">API URL</label></th>
<td>
<input type="text" id="ifnex_api_url" name="ifnex_api_url" value="<?php echo esc_attr($api_url); ?>" class="regular-text" placeholder="http://localhost:8000/api/v1">
<p class="description">آدرس پایه API لاراول</p>
</td>
</tr>
<tr>
<th scope="row"><label for="ifnex_api_key">API Key (عمومی)</label></th>
<td>
<input type="text" id="ifnex_api_key" name="ifnex_api_key" value="<?php echo esc_attr($api_key); ?>" class="regular-text">
<p class="description">برای APIهای عمومی مثل Tracking</p>
</td>
</tr>
<tr style="background: #fff3cd;">
<th scope="row"><label for="ifnex_bridge_api_key">🔐 Bridge API Key</label></th>
<td>
<input type="text" id="ifnex_bridge_api_key" name="ifnex_bridge_api_key" value="<?php echo esc_attr($bridge_api_key); ?>" class="regular-text">
<p class="description"><strong>مهم:</strong> باید با مقدار <code>IFNEX_BRIDGE_API_KEY</code> در فایل <code>.env</code> لاراول یکسان باشد.</p>
</td>
</tr>
</table>
<?php submit_button('ذخیره تنظیمات'); ?>
</form>
<hr>
<h2>راهنمای راه‌اندازی</h2>
<ol>
<li>در فایل <code>.env</code> لاراول، خط <code>IFNEX_BRIDGE_API_KEY=your-secret-key</code> را تنظیم کنید</li>
<li>همان مقدار را در فیلد "Bridge API Key" بالا وارد کنید</li>
<li>کاربران وردپرس باید در لاراول با همان ایمیل موجود باشند (از <code>php artisan ifnex:sync-wp-users</code> استفاده کنید)</li>
</ol>
</div>
<?php
}