HEX
Server: nginx/1.18.0
System: Linux oas2 6.8.0-1039-oracle #40~22.04.1-Ubuntu SMP Wed Oct 29 05:11:00 UTC 2025 aarch64
User: root (0)
PHP: 8.1.2-1ubuntu2.23
Disabled: NONE
Upload Files
File: /var/www/ecom/wp-content/plugins/woocommerce-alidropship/admin/log.php
<?php

/**
 * Class VI_WOOCOMMERCE_ALIDROPSHIP_Admin_Log
 *
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

//ini_set( 'auto_detect_line_endings', true );

class VI_WOOCOMMERCE_ALIDROPSHIP_Admin_Log {
	public function __construct() {
		add_action( 'wp_ajax_vi_wad_view_log', array( $this, 'generate_log_ajax' ) );
		add_action( 'admin_menu', array( $this, 'admin_menu' ), 19 );
		add_action( 'admin_init', array( $this, 'encrypt_log_file' ), 0 );
		add_action( 'admin_init', array( $this, 'admin_init' ) );
		add_action( 'admin_init', array( $this, 'download_log_file' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'wc_logs_enqueue_scripts' ) );
	}

	/**
	 * Use js to remove ALD- log files from WC/Status/Logs page because no PHP filters available
	 */
	public function wc_logs_enqueue_scripts() {
		global $pagenow;
		$page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$tab  = isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : '';// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( $pagenow === 'admin.php' && $page === 'wc-status' && $tab === 'logs' ) {
			wp_enqueue_script( 'woocommerce-alidropship-wc-logs', VI_WOOCOMMERCE_ALIDROPSHIP_JS . 'wc-logs.js', array( 'jquery' ), VI_WOOCOMMERCE_ALIDROPSHIP_VERSION, false );
		}
	}

	public function encrypt_log_file() {
		if ( ! get_option( 'vi_wad_log_file_prefix' ) ) {
			$prefix    = wp_hash( 'ald-log_' . time() );
			$log_files = self::log_files();
			foreach ( $log_files as $file_name ) {
				if ( is_file( VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . $file_name . '.txt' ) ) {
					@rename( VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . $file_name . '.txt', VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . $prefix . '_' . $file_name . '.txt' );// phpcs:ignore WordPress.WP.AlternativeFunctions.rename_rename
				}
			}
			update_option( 'vi_wad_log_file_prefix', $prefix );
		}
	}

	public function download_log_file() {
		$nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( $_POST['_wpnonce'] ) : '';
		if ( $nonce && wp_verify_nonce( $nonce, 'vi_wad_download_log' ) ) {
			$file = '';
			if ( isset( $_POST['vi_wad_download_log'] ) ) {
				$prefix   = get_option( 'vi_wad_log_file_prefix' );
				$log_file = sanitize_text_field( $_POST['vi_wad_download_log'] );
				if ( in_array( str_replace( $prefix . '_', '', $log_file ), $this->log_files() ) ) {
					$file = VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . $log_file . '.txt';
				}
			} else {
				$logs = WC_Log_Handler_File::get_log_files();
				if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) { // WPCS: input var ok, CSRF ok.
					$log_file = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ]; // WPCS: input var ok, CSRF ok.
					$file     = WC_LOG_DIR . $log_file;
				}
			}
			if ( is_file( $file ) ) {
				$fh = @fopen( 'php://output', 'w' );
				fprintf( $fh, chr( 0xEF ) . chr( 0xBB ) . chr( 0xBF ) );
				header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
				header( 'Content-Description: File Transfer' );
				header( 'Content-type: text/csv' );
				header( 'Content-Disposition: attachment; filename=' . $log_file . '__' . date( 'Y-m-d_H-i-s' ) . '.txt' );// phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
				header( 'Expires: 0' );
				header( 'Pragma: public' );
				fputs( $fh, file_get_contents( $file ) );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPress.WP.AlternativeFunctions.file_system_operations_fputs
				fclose( $fh );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
				die();
			}
		}
	}

	public function admin_init() {
		global $pagenow;
		$page   = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
		$action = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : '';
		if ( $pagenow === 'admin.php' && $page === 'woocommerce-alidropship-logs' ) {
			add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
			if ( $action === 'vi_wad_delete_log' ) {
				$nonce    = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( $_GET['_wpnonce'] ) : '';
				$log_file = isset( $_GET['vi_wad_file_name'] ) ? sanitize_text_field( $_GET['vi_wad_file_name'] ) : '';
				$prefix   = get_option( 'vi_wad_log_file_prefix' );
				if ( wp_verify_nonce( $nonce, 'vi_wad_delete_log' ) && in_array( str_replace( $prefix . '_', '', $log_file ), $this->log_files() ) ) {
					$file = VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . $log_file . '.txt';
					if ( is_file( $file ) ) {
						wp_delete_file( $file );
						wp_safe_redirect( admin_url( 'admin.php?page=woocommerce-alidropship-logs' ) );
						exit();
					}
				}
			}
		}
	}

	public function admin_enqueue_scripts() {
		wp_enqueue_style( 'woocommerce-alidropship-message', VI_WOOCOMMERCE_ALIDROPSHIP_CSS . 'message.min.css', '', VI_WOOCOMMERCE_ALIDROPSHIP_VERSION );
		wp_enqueue_style( 'woocommerce-alidropship-logs', VI_WOOCOMMERCE_ALIDROPSHIP_CSS . 'logs.css', '', VI_WOOCOMMERCE_ALIDROPSHIP_VERSION );
		wp_enqueue_script( 'woocommerce-alidropship-logs', VI_WOOCOMMERCE_ALIDROPSHIP_JS . 'logs.js', array( 'jquery' ), VI_WOOCOMMERCE_ALIDROPSHIP_VERSION, false );
	}

	public function admin_menu() {
		$menu_slug = 'woocommerce-alidropship-logs';
		add_submenu_page( 'woocommerce-alidropship-import-list',
			esc_html__( 'Logs - AliExpress Dropshipping and Fulfillment for WooCommerce', 'woocommerce-alidropship' ),
			esc_html__( 'Logs', 'woocommerce-alidropship' ),
			apply_filters( 'vi_wad_admin_sub_menu_capability', 'manage_options', $menu_slug ),
			$menu_slug,
			array( $this, 'page_callback' ) );
	}

	public function log_files() {
		return array(
			'update_products',
			'cron_update_products',
			'cron_update_orders',
			'migrate_products',
			'debug'
		);
	}

	public function page_callback() {
		?>
        <div class="wrap">
            <h2><?php esc_html_e( 'Your logs show here', 'woocommerce-alidropship' ) ?></h2>
            <form class="" action="" method="post">
				<?php
				wp_nonce_field( 'vi_wad_download_log' );
				$log_files = $this->log_files();
				$old_log   = '';
				foreach ( $log_files as $log_file ) {
					$log_file = self::build_log_file_name( $log_file );
					if ( is_file( $log_file ) ) {
						ob_start();
						?>
                        <li>
							<?php
							self::print_log_html( array( $log_file ) );
							?>
                        </li>
						<?php
						$old_log .= ob_get_clean();
					}
				}
				if ( $old_log ) {
					?>
                    <div class="vi-ui warning message">
                        <div class="header"><?php esc_html_e( 'Below are log files from versions before 1.0.9', 'woocommerce-alidropship' ) ?></div>
                        <ul class="list">
							<?php
							echo $old_log;// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
							?>
                        </ul>
                    </div>
					<?php
				}
				?>
            </form>
            <div class="vi-ui positive message">
                <div class="header"><?php esc_html_e( 'Since version 1.0.9, all log files are stored in the same log folder of WooCommerce.', 'woocommerce-alidropship' ) ?></div>
                <ul class="list">
                    <li><?php echo wp_kses_post( sprintf( esc_html__( 'Log folder: %s', 'woocommerce-alidropship' ), WC_LOG_DIR )) //phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment ?></li>
                    <li><?php echo wp_kses_post(sprintf( esc_html__( 'Log files older than %s days will be automatically deleted by WooCommerce', 'woocommerce-alidropship' ), apply_filters( 'woocommerce_logger_days_to_retain_logs', 30 ) )) //phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment ?></li>
                </ul>
            </div>
			<?php
			if ( class_exists( 'WC_Log_Handler_File' ) ) {
				$logs = WC_Log_Handler_File::get_log_files();
				if ( !empty( $logs ) ) {
					foreach ( $logs as $key => $value ) {
						if ( substr( $key, 0, 4 ) !== 'ald-' ) {
							unset( $logs[ $key ] );
						}
					}
				}
				if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) { // WPCS: input var ok, CSRF ok.
					$viewed_log = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ]; // WPCS: input var ok, CSRF ok.
				} elseif ( ! empty( $logs ) ) {
					$viewed_log = current( $logs );
				}

				if ( ! empty( $_REQUEST['handle'] ) ) { // WPCS: input var ok, CSRF ok.
					if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'remove_log' ) ) { // WPCS: input var ok, sanitization ok.
						wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
					}
					if ( ! empty( $_REQUEST['handle'] ) ) {  // WPCS: input var ok.
						$log_handler = new WC_Log_Handler_File();
						$log_handler->remove( wp_unslash( $_REQUEST['handle'] ) ); // WPCS: input var ok, sanitization ok.
					}
					wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=woocommerce-alidropship-logs' ) ) );
					exit();
				}
				$log_of = isset( $_REQUEST['log_of'] ) ? sanitize_text_field( $_REQUEST['log_of'] ) : '';
				if ( $logs ) {
					$logs = array_reverse( $logs );
					?>
                    <div id="log-viewer-select">
                        <div class="alignleft">
                            <h2>
								<?php
								echo esc_html( $viewed_log );
								if ( ! empty( $viewed_log ) ) { ?>
                                    <a class="page-title-action vi-wad-delete-log"
                                       href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'handle' => sanitize_title( $viewed_log ) ), admin_url( 'admin.php?page=woocommerce-alidropship-logs' ) ), 'remove_log' ) ); ?>"
                                       class="button"><?php esc_html_e( 'Delete log', 'woocommerce' ); ?></a>
									<?php
								}
								?>
                            </h2>
                        </div>
                        <div class="alignright">
                            <form class="vi-wad-logs-form"
                                  action="<?php echo esc_url( admin_url( 'admin.php?page=woocommerce-alidropship-logs' ) ); ?>"
                                  method="post">
                                <select name="log_of">
                                    <option value=""><?php esc_html_e( 'All log files', 'woocommerce-alidropship' ) ?></option>
                                    <option value="manual-products-sync" <?php selected( $log_of, 'manual-products-sync' ); ?>><?php esc_html_e( 'Manual products sync', 'woocommerce-alidropship' ) ?></option>
                                    <option value="api-products-sync" <?php selected( $log_of, 'api-products-sync' ); ?>><?php esc_html_e( 'API products sync', 'woocommerce-alidropship' ) ?></option>
                                    <option value="migrate-products" <?php selected( $log_of, 'migrate-products' ); ?>><?php esc_html_e( 'Products migration', 'woocommerce-alidropship' ) ?></option>
                                    <option value="api-orders-sync" <?php selected( $log_of, 'api-orders-sync' ); ?>><?php esc_html_e( 'Orders sync', 'woocommerce-alidropship' ) ?></option>
                                    <option value="api-fulfill-order" <?php selected( $log_of, 'api-fulfill-order' ); ?>><?php esc_html_e( 'Auto fulfill order', 'woocommerce-alidropship' ) ?></option>
                                    <option value="debug" <?php selected( $log_of, 'debug' ); ?>><?php esc_html_e( 'Debug', 'woocommerce-alidropship' ) ?></option>
                                </select>
                                <select name="log_file">
                                    <option value=""><?php esc_html_e( 'No files found', 'woocommerce-alidropship' ) ?></option>
									<?php
									foreach ( $logs as $log_key => $log_file ) {
										$timestamp = filemtime( WC_LOG_DIR . $log_file );
										$date      = sprintf(
										/* translators: 1: last access date 2: last access time 3: last access timezone abbreviation */
											__( '%1$s at %2$s %3$s', 'woocommerce' ),
											wp_date( wc_date_format(), $timestamp ),
											wp_date( wc_time_format(), $timestamp ),
											wp_date( 'T', $timestamp )
										);
										?>
                                        <option value="<?php echo esc_attr( $log_key ); ?>" <?php selected( sanitize_title( $viewed_log ), $log_key ); ?>><?php echo esc_html( $log_file ); ?>
                                            (<?php echo esc_html( $date ); ?>)
                                        </option>
										<?php
									}
									?>
                                </select>
                                <button type="submit" class="button"
                                        value="<?php esc_attr_e( 'View', 'woocommerce' ); ?>"><?php esc_html_e( 'View', 'woocommerce' ); ?></button>
                                <button type="submit" class="button" name="_wpnonce"
                                        title="<?php esc_attr_e( 'Download selected log file to your device', 'woocommerce-alidropship' ); ?>"
                                        value="<?php echo esc_attr( wp_create_nonce( 'vi_wad_download_log' ) ); ?>"><?php esc_html_e( 'Download', 'woocommerce-alidropship' ); ?></button>
                            </form>
                        </div>
                        <div class="clear"></div>
                    </div>
                    <div id="log-viewer">
                        <pre><?php echo esc_html( file_get_contents( WC_LOG_DIR . $viewed_log ) );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents ?></pre>
                    </div>
					<?php
				} else {
					?>
                    <div class="updated woocommerce-message inline">
                        <p><?php esc_html_e( 'There are currently no logs to view.', 'woocommerce' ); ?></p></div>
					<?php
				}
			}
			?>
        </div>
		<?php
	}

	public function generate_log_ajax() {
		check_ajax_referer( 'woocommerce_alidropship_admin_ajax', '_vi_wad_ajax_nonce' );
		/*Check the nonce*/
		if ( ! current_user_can( apply_filters( 'vi_wad_admin_sub_menu_capability', 'manage_options', 'woocommerce-alidropship-logs' ) ) || empty( $_GET['action'] ) || ! check_admin_referer( wp_unslash( $_GET['action'] ) ) ) {
			wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'woocommerce-alidropship' ) );
		}
		if ( empty( $_GET['vi_wad_file'] ) ) {
			wp_die( esc_html__( 'No log file selected.', 'woocommerce-alidropship' ) );
		}
		$file = urldecode( wp_unslash( $_GET['vi_wad_file'] ) );
		if ( ! is_file( $file ) ) {
			wp_die( esc_html__( 'Log file not found.', 'woocommerce-alidropship' ) );
		}
		echo( wp_kses_post( nl2br( file_get_contents( $file ) ) ) );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		exit();
	}

	public static function error_log( $logs_content = '' ) {
		self::log( $logs_content, 'debug.txt' );
	}

	public static function wc_log( $content, $source = 'debug', $level = 'info' ) {
		$content = $source ==='viwad_check'? $content : wp_strip_all_tags( $content );
		$log     = wc_get_logger();
		$log->log( $level, $content, array( 'source' => 'ALD-' . $source, ) );
	}

	public static function log( $logs_content = '', $file_name = 'update_products.txt' ) {
		$log_file = self::build_log_file_name( $file_name );
		if ( $logs_content ) {
			$logs_content = "[" . date( "Y-m-d H:i:s" ) . "] {$logs_content}";// phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
		}
		$logs_content .= PHP_EOL;
		if ( is_file( $log_file ) ) {
			file_put_contents( $log_file, $logs_content, FILE_APPEND );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
		} else {
			self::create_plugin_cache_folder();
			file_put_contents( $log_file, $logs_content );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
		}
	}

	public static function print_log_html( $logs ) {
		if ( is_array( $logs ) && !empty( $logs ) ) {
			$page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			foreach ( $logs as $log ) {
				?>
                <p><?php echo wp_kses_post( $log ) ?>
                    <a target="_blank" href="<?php echo esc_url( add_query_arg( array(
						'action'             => 'vi_wad_view_log',
						'_vi_wad_ajax_nonce' => VI_WOOCOMMERCE_ALIDROPSHIP_Admin_Settings::create_ajax_nonce(),
						'vi_wad_file'        => urlencode( $log ),
						'_wpnonce'           => wp_create_nonce( 'vi_wad_view_log' ),
					), admin_url( 'admin-ajax.php' ) ) ) ?>"><?php esc_html_e( 'View log', 'woocommerce-alidropship' ) ?>
                    </a>
					<?php
					if ( $page === 'woocommerce-alidropship-logs' ) {
						$file_name = explode( '.', substr( $log, strlen( VI_WOOCOMMERCE_ALIDROPSHIP_CACHE ) ) )[0];
						?>
                        ,
                        <a class="vi-wad-delete-log" href="<?php echo esc_url( add_query_arg( array(
							'action'           => 'vi_wad_delete_log',
							'vi_wad_file_name' => $file_name,
							'_wpnonce'         => wp_create_nonce( 'vi_wad_delete_log' ),
						) ) ) ?>"><?php esc_html_e( 'Delete', 'woocommerce-alidropship' ) ?>
                        </a>
						<?php
						esc_html_e( ' or ', 'woocommerce-alidropship' );
						?>
                        <button type="submit" name="vi_wad_download_log" value="<?php echo esc_attr( $file_name ) ?>"
                                class="vi-wad-download-log"><?php esc_html_e( 'Download log file', 'woocommerce-alidropship' ) ?>
                        </button>
						<?php
					}
					?>
                </p>
				<?php
			}
		}
	}

	public static function create_plugin_cache_folder() {
		if ( ! is_dir( VI_WOOCOMMERCE_ALIDROPSHIP_CACHE ) ) {
			wp_mkdir_p( VI_WOOCOMMERCE_ALIDROPSHIP_CACHE );
			file_put_contents( VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . '.htaccess', // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
                '<IfModule !mod_authz_core.c>
                Order deny,allow
                Deny from all
                </IfModule>
                <IfModule mod_authz_core.c>
                  <RequireAll>
                    Require all denied
                  </RequireAll>
                </IfModule>
                ' );
		}
	}

	public static function build_log_file_name( $log_file ) {
		$prefix = get_option( 'vi_wad_log_file_prefix' );
		if ( $prefix ) {
			$prefix .= '_';
		}
		$ext      = '';
		$pathinfo = pathinfo( $log_file );
		if ( empty( $pathinfo['extension'] ) ) {
			$ext = '.txt';
		}

		return VI_WOOCOMMERCE_ALIDROPSHIP_CACHE . $prefix . $log_file . $ext;
	}
}