--- a/notificationx/assets/admin/js/admin.asset.php
+++ b/notificationx/assets/admin/js/admin.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-i18n', 'wp-media-utils', 'wp-polyfill'), 'version' => '78849eed812f914ec657');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-i18n', 'wp-media-utils', 'wp-polyfill'), 'version' => 'e55707f8a8c3fa5c6556');
--- a/notificationx/includes/Admin/Admin.php
+++ b/notificationx/includes/Admin/Admin.php
@@ -199,7 +199,7 @@
public function hide_others_plugin_admin_notice()
{
$current_screen = get_current_screen();
- $hide_on = ['toplevel_page_nx-admin', 'notificationx_page_nx-dashboard', 'notificationx_page_nx-edit','notificationx_page_nx-settings','notificationx_page_nx-analytics','notificationx_page_nx-builder'];
+ $hide_on = ['toplevel_page_nx-admin', 'notificationx_page_nx-dashboard', 'notificationx_page_nx-edit','notificationx_page_nx-settings','notificationx_page_nx-analytics','notificationx_page_nx-builder', 'notificationx_page_nx-feedback-entries'];
if ( $current_screen && isset( $current_screen->base ) && in_array($current_screen->base, $hide_on) ) {
remove_all_actions('user_admin_notices');
remove_all_actions('admin_notices');
@@ -343,6 +343,7 @@
]
);
+ // Black Friday 2025
$notice_text = "<p><strong>Black Friday Mega Sale:</strong> Boost trust & conversions with real-time social proof notification alerts – now <strong>up to $160 OFF! 🎁</strong> </p><div class='wpsp-notice-action-button' style='display: inline-flex;column-gap:5px;'><a class='button button-primary' href='https://notificationx.com/bfcm2025-admin-notice' target='_blank'>Upgrade To PRO</a> <button class='wpsp-notice-action-dismiss dismiss-btn' data-dismiss='true' target='_blank'>I’ll Grab It Later</button></div>";
$_black_friday_2025 = [
'thumbnail' => self::ASSET_URL . 'images/full-logo.svg',
@@ -361,6 +362,27 @@
'display_if' => !is_array( $notices->is_installed( 'notificationx-pro/notificationx-pro.php' ) ),
]
);
+
+ // Holiday Deal
+ $notice_text = "<p><strong>Season's Best Deal:</strong> Boost trust & conversions with real-time social proof notification alerts – now <strong>up to 25% OFF! ⚡</strong> </p><div class='wpsp-notice-action-button' style='display: inline-flex;column-gap:5px;'><a class='button button-primary' href='https://notificationx.com/holiday2025-admin-notice' target='_blank'>Upgrade To PRO</a> <button class='wpsp-notice-action-dismiss dismiss-btn' data-dismiss='true' target='_blank'>I’ll Grab It Later</button></div>";
+ $_nx_holiday_2025 = [
+ 'thumbnail' => self::ASSET_URL . 'images/full-logo.svg',
+ 'html' => $notice_text,
+ ];
+ $notices->add(
+ 'nx_holiday_2025',
+ $_nx_holiday_2025,
+ [
+ 'start' => $notices->time(),
+ 'recurrence' => false,
+ 'dismissible' => true,
+ 'refresh' => NOTIFICATIONX_VERSION,
+ 'screens' => [ 'dashboard' ],
+ "expire" => strtotime( '11:59:59pm 7th January, 2026' ),
+ "start" => strtotime( '11:59:59pm 15th December, 2025' ),
+ 'display_if' => !is_array( $notices->is_installed( 'notificationx-pro/notificationx-pro.php' ) ),
+ ]
+ );
// Holiday Deal
$notice_text = "<p>🎁 <strong>SAVE 25% now</strong> & unlock advanced social-proof marketing features to skyrocket conversions in 2025.</p>
--- a/notificationx/includes/Admin/DashboardWidget.php
+++ b/notificationx/includes/Admin/DashboardWidget.php
@@ -60,6 +60,9 @@
* @return void
*/
public function widget_action(){
+ if( ! current_user_can( 'read_notificationx_analytics' ) ) {
+ return;
+ }
wp_add_dashboard_widget( self::WIDGET_ID, $this->widget_name, array( $this, 'widget_output' ) );
}
/**
--- a/notificationx/includes/Admin/InfoTooltipManager.php
+++ b/notificationx/includes/Admin/InfoTooltipManager.php
@@ -93,6 +93,20 @@
'width' => '450',
'height' => '235',
],
+ 'popup_notification_message_field' => [
+ 'type' => 'content',
+ 'title' => 'Enable this field to let users send messages or feedback.','notificationx',
+ 'content' => '',
+ 'width' => '450',
+ 'height' => '235',
+ ],
+ 'popup_notification_email_field' => [
+ 'type' => 'content',
+ 'title' => 'Enable this field to collect user's email addresses.','notificationx',
+ 'content' => '',
+ 'width' => '450',
+ 'height' => '235',
+ ],
];
@@ -125,11 +139,13 @@
esc_attr($tooltip['title'])
);
} else {
- $html .= sprintf('<p>%s</p>', wp_kses_post($tooltip['content']));
+ if( !empty($tooltip['content']) ) {
+ $html .= sprintf('<p style="margin-bottom:5px;">%s</p>', wp_kses_post($tooltip['content']));
+ }
}
if (!empty($tooltip['title'])) {
- $html .= '<h3 style="margin:5px 0;">' . wp_kses_post($tooltip['title']);
+ $html .= '<h3 style="margin-bottom:5px;">' . wp_kses_post($tooltip['title']);
$html .= '</h3>';
}
--- a/notificationx/includes/Admin/Settings.php
+++ b/notificationx/includes/Admin/Settings.php
@@ -441,6 +441,21 @@
],
]
),
+ 'entries' => apply_filters('nx_settings_tab_entries', [
+ 'label' => __( 'Entries', 'notificationx' ),
+ 'id' => 'entries',
+ 'classes' => 'tab-advanced-settings',
+ 'priority' => 35,
+ 'fields' => [
+ 'feedback_entries' => array(
+ 'name' => 'feedback_entries',
+ 'priority' => 10,
+ 'type' => 'feedback-entries',
+ 'label' => __( 'Analytics', 'notificationx' ),
+ ),
+ ],
+ ]
+ ),
'cache_settings_tab' => apply_filters('nx_settings_tab_cache', [
'id' => 'tab-cache-settings',
'label' => __( 'Cache Settings', 'notificationx' ),
--- a/notificationx/includes/Core/Modules.php
+++ b/notificationx/includes/Core/Modules.php
@@ -65,10 +65,10 @@
*/
public function is_enabled($module) {
$enabled_types = (array) Settings::get_instance()->get('settings.modules');
-
- if( isset( $enabled_types[ $module ] ) && $enabled_types[$module] ) {
- return $enabled_types[$module];
- } elseif( ! isset( $enabled_types[ $module ] ) ) {
+ $module_key = $module ?? ''; // Use empty string if null
+ if( isset( $enabled_types[ $module_key ] ) && $enabled_types[ $module_key] ) {
+ return $enabled_types[ $module_key ];
+ } elseif( ! isset( $enabled_types[ $module_key ] ) ) {
return true;
}
--- a/notificationx/includes/Core/PostType.php
+++ b/notificationx/includes/Core/PostType.php
@@ -85,7 +85,7 @@
* @return void
*/
function admin_enqueue_scripts( $hook ) {
- if ( $hook !== 'toplevel_page_nx-admin' && $hook !== 'notificationx_page_nx-edit' && $hook !== 'notificationx_page_nx-settings' && $hook !== 'notificationx_page_nx-analytics' && $hook !== 'notificationx_page_nx-dashboard' && $hook !== 'notificationx_page_nx-builder' ) {
+ if ( $hook !== 'toplevel_page_nx-admin' && $hook !== 'notificationx_page_nx-edit' && $hook !== 'notificationx_page_nx-settings' && $hook !== 'notificationx_page_nx-analytics' && $hook !== 'notificationx_page_nx-dashboard' && $hook !== 'notificationx_page_nx-builder' && $hook !== 'notificationx_page_nx-feedback-entries' ) {
return;
}
// @todo not sure why did it. maybe remove.
@@ -436,11 +436,35 @@
public function get_post_with_analytics( $wheres = [], $extra_query = '' ) {
$posts = $this->get_posts( $wheres, 'a.*, SUM(b.clicks) AS clicks, SUM(b.views) AS views', Database::$table_stats, 'a.nx_id', 'LEFT JOIN', $extra_query );
+
+ // Get entries count for popup notifications
+ global $wpdb;
+ $entries_table = $wpdb->prefix . 'nx_entries';
+ $entries_counts = $wpdb->get_results(
+ "SELECT nx_id, COUNT(*) as entries_count
+ FROM {$entries_table}
+ WHERE source = 'popup_notification'
+ GROUP BY nx_id",
+ ARRAY_A
+ );
+
+ // Create a lookup array for entries counts
+ $entries_lookup = [];
+ foreach ($entries_counts as $entry) {
+ $entries_lookup[$entry['nx_id']] = $entry['entries_count'];
+ }
+
foreach ( $posts as $key => $post ) {
$source = $post['source'];
$posts[ $key ]['can_regenerate'] = false;
$extension = ExtensionFactory::get_instance()->get( $source );
$posts[ $key ]['source_label'] = $extension->title;
+
+ // Add entries count for popup notifications
+ if ($source === 'popup_notification') {
+ $posts[ $key ]['entries'] = isset($entries_lookup[$post['nx_id']]) ? $entries_lookup[$post['nx_id']] : 0;
+ }
+
if ( ! empty( $extension ) && method_exists( $extension, 'get_notification_ready' ) && $extension->is_active( false ) ) {
$posts[ $key ]['can_regenerate'] = true;
}
--- a/notificationx/includes/Core/REST.php
+++ b/notificationx/includes/Core/REST.php
@@ -52,6 +52,7 @@
RestEntries::get_instance();
RestAnalytics::get_instance();
RestBulkAction::get_instance();
+ RestPopup::get_instance();
add_action('rest_api_init', [$this, 'register_routes']);
$enable_rest_api = Settings::get_instance()->get('settings.enable_rest_api', false);
--- a/notificationx/includes/Core/Rest/Entries.php
+++ b/notificationx/includes/Core/Rest/Entries.php
@@ -125,6 +125,7 @@
* @return WP_Error|bool
*/
public function check_permission( $request ) {
- return current_user_can( 'edit_posts' );
+ // return current_user_can( 'edit_posts' );
+ return current_user_can( 'edit_notificationx' );
}
}
No newline at end of file
--- a/notificationx/includes/Core/Rest/Popup.php
+++ b/notificationx/includes/Core/Rest/Popup.php
@@ -0,0 +1,475 @@
+<?php
+
+namespace NotificationXCoreRest;
+
+use NotificationXGetInstance;
+use NotificationXCorePopupNotification;
+use NotificationXExtensionsPopupPopupNotification as PopupPopupNotification;
+use NotificationXNotificationX;
+use WP_REST_Server;
+
+/**
+ * @method static Popup get_instance($args = null)
+ */
+class Popup {
+ /**
+ * Instance of Popup
+ *
+ * @var Popup
+ */
+ use GetInstance;
+ public $namespace;
+ public $rest_base;
+ public $id = 'popup_notification';
+
+ /**
+ * Constructor.
+ *
+ * @since 4.7.0
+ *
+ * @param string $post_type Post type.
+ */
+ public function __construct() {
+ $this->namespace = 'notificationx/v1';
+ $this->rest_base = 'popup-submit';
+ add_action('rest_api_init', [$this, 'register_routes']);
+ }
+
+
+ /**
+ * Registers the routes for the objects of the controller.
+ *
+ * @since 3.1.12
+ *
+ * @see register_rest_route()
+ */
+ public function register_routes() {
+ register_rest_route('notificationx/v1', '/popup-submit', [
+ 'methods' => 'POST',
+ 'callback' => [ $this , 'handle_popup_submission' ],
+ 'permission_callback' => '__return_true',
+ 'args' => [
+ 'nx_id' => [
+ 'required' => true,
+ 'type' => 'string',
+ ],
+ 'email' => [
+ 'type' => 'string',
+ 'sanitize_callback' => 'sanitize_email',
+ ],
+ 'message' => [
+ 'type' => 'string',
+ 'sanitize_callback' => 'sanitize_textarea_field',
+ ],
+ 'name' => [
+ 'type' => 'string',
+ 'sanitize_callback' => 'sanitize_textarea_field',
+ ],
+ 'timestamp' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ]);
+
+ // Feedback entries endpoint
+ register_rest_route('notificationx/v1', '/feedback-entries', [
+ 'methods' => 'GET',
+ 'callback' => [$this, 'get_feedback_entries'],
+ 'permission_callback' => function() {
+ return current_user_can('read_notificationx');
+ },
+ 'args' => [
+ 'page' => [
+ 'default' => 1,
+ 'type' => 'integer',
+ 'minimum' => 1,
+ ],
+ 'per_page' => [
+ 'default' => 20,
+ 'type' => 'integer',
+ 'minimum' => 1,
+ 'maximum' => 200,
+ ],
+ 's' => [
+ 'default' => '',
+ 'type' => 'string',
+ 'sanitize_callback' => 'sanitize_text_field',
+ ],
+ 'notification_id' => [
+ 'default' => '',
+ 'type' => 'string',
+ 'sanitize_callback' => 'sanitize_text_field',
+ ],
+ ],
+ ]);
+
+ // Delete feedback entry endpoint
+ register_rest_route('notificationx/v1', '/feedback-entries/(?P<id>d+)', [
+ 'methods' => 'DELETE',
+ 'callback' => [$this, 'delete_feedback_entry'],
+ 'permission_callback' => function() {
+ return current_user_can('edit_notificationx');
+ },
+ 'args' => [
+ 'id' => [
+ 'required' => true,
+ 'type' => 'integer',
+ ],
+ ],
+ ]);
+
+ // Bulk delete feedback entries endpoint
+ register_rest_route('notificationx/v1', '/feedback-entries/bulk-delete', [
+ 'methods' => 'POST',
+ 'callback' => [$this, 'bulk_delete_feedback_entries'],
+ 'permission_callback' => function() {
+ return current_user_can('edit_notificationx');
+ },
+ 'args' => [
+ 'ids' => [
+ 'required' => true,
+ 'type' => 'array',
+ 'items' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
+ ]);
+
+ // Export feedback entries endpoint
+ register_rest_route('notificationx/v1', '/feedback-entries/export', [
+ 'methods' => 'POST',
+ 'callback' => [$this, 'export_feedback_entries'],
+ 'permission_callback' => function() {
+ return current_user_can('read_notificationx');
+ },
+ 'args' => [
+ 's' => [
+ 'required' => false,
+ 'type' => 'string',
+ ],
+ 'notification_id' => [
+ 'required' => false,
+ 'type' => 'string',
+ ],
+ ],
+ ]);
+ }
+
+ /**
+ * Handle popup form submission
+ *
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response
+ */
+ public function handle_popup_submission($request) {
+ $popup = PopupPopupNotification::get_instance();
+ return $popup->handle_popup_submission($request);
+ }
+
+
+ /**
+ * Get feedback entries
+ *
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response
+ */
+ public function get_feedback_entries($request) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . 'nx_entries';
+
+ // Get pagination parameters
+ $page = $request->get_param('page') ?: 1;
+ $per_page = $request->get_param('per_page') ?: 20;
+ $search = $request->get_param('s') ?: '';
+ $notification_id = $request->get_param('notification_id') ?: '';
+ $offset = ($page - 1) * $per_page;
+
+ // Build WHERE clause
+ $where_conditions = ["e.source = %s"];
+ $where_values = [$this->id];
+
+ // Add notification filter
+ if (!empty($notification_id)) {
+ $where_conditions[] = "e.nx_id = %d";
+ $where_values[] = intval($notification_id);
+ }
+
+ // Add search functionality
+ if (!empty($search)) {
+ $where_conditions[] = "(e.data LIKE %s OR e.created_at LIKE %s)";
+ $search_term = '%' . $wpdb->esc_like($search) . '%';
+ $where_values[] = $search_term;
+ $where_values[] = $search_term;
+ }
+
+ $where_clause = implode(' AND ', $where_conditions);
+
+ // Get total count for pagination
+ $total_query = $wpdb->prepare(
+ "SELECT COUNT(*) FROM {$table_name} e WHERE {$where_clause}",
+ ...$where_values
+ );
+ $total_items = (int) $wpdb->get_var($total_query);
+
+ // Get paginated entries with notification information
+ $posts_table = $wpdb->prefix . 'nx_posts';
+ $entries_query = $wpdb->prepare(
+ "SELECT e.*, p.title as notification_name, p.nx_id as notification_id
+ FROM {$table_name} e
+ LEFT JOIN {$posts_table} p ON e.nx_id = p.nx_id
+ WHERE {$where_clause}
+ ORDER BY e.created_at DESC
+ LIMIT %d OFFSET %d",
+ ...array_merge($where_values, [$per_page, $offset])
+ );
+ $entries = $wpdb->get_results($entries_query, ARRAY_A);
+
+ $formatted_entries = [];
+ foreach ($entries as $entry) {
+ $data = maybe_unserialize($entry['data']);
+ $formatted_entries[] = [
+ 'id' => $entry['entry_id'],
+ 'date' => $entry['created_at'],
+ 'name' => $data['name'] ?? '',
+ 'email' => $data['email'] ?? '',
+ 'message' => $data['message'] ?? '',
+ 'title' => $data['title'] ?? '',
+ 'theme' => $data['theme'] ?? '',
+ 'ip' => $data['ip'] ?? '',
+ 'notification_name' => $entry['notification_name'] ?? '',
+ 'notification_id' => $entry['notification_id'] ?? 0,
+ 'nx_id' => $entry['nx_id'] ?? 0,
+ ];
+ }
+
+ return new WP_REST_Response([
+ 'entries' => $formatted_entries,
+ 'total' => $total_items,
+ 'page' => $page,
+ 'per_page' => $per_page,
+ 'total_pages' => ceil($total_items / $per_page),
+ ], 200);
+ }
+
+ /**
+ * Delete feedback entry
+ *
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response
+ */
+ public function delete_feedback_entry($request) {
+ global $wpdb;
+
+ $entry_id = $request->get_param('id');
+ $table_name = $wpdb->prefix . 'nx_entries';
+
+ $result = $wpdb->delete(
+ $table_name,
+ [
+ 'entry_id' => $entry_id,
+ 'source' => $this->id
+ ],
+ ['%d', '%s']
+ );
+
+ if ($result === false) {
+ return new WP_REST_Response([
+ 'success' => false,
+ 'message' => __('Failed to delete entry', 'notificationx'),
+ ], 500);
+ }
+
+ return new WP_REST_Response([
+ 'success' => true,
+ 'message' => __('Entry deleted successfully', 'notificationx'),
+ ], 200);
+ }
+
+ /**
+ * Bulk delete feedback entries
+ *
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response
+ */
+ public function bulk_delete_feedback_entries($request) {
+ global $wpdb;
+
+ $entry_ids = $request->get_param('ids');
+ $table_name = $wpdb->prefix . 'nx_entries';
+
+ if (empty($entry_ids) || !is_array($entry_ids)) {
+ return new WP_REST_Response([
+ 'success' => false,
+ 'message' => __('No entries selected for deletion', 'notificationx'),
+ ], 400);
+ }
+
+ // Sanitize entry IDs
+ $entry_ids = array_map('absint', $entry_ids);
+ $entry_ids = array_filter($entry_ids); // Remove any zero values
+
+ if (empty($entry_ids)) {
+ return new WP_REST_Response([
+ 'success' => false,
+ 'message' => __('Invalid entry IDs provided', 'notificationx'),
+ ], 400);
+ }
+
+ // Create placeholders for the IN clause
+ $placeholders = implode(',', array_fill(0, count($entry_ids), '%d'));
+
+ // Prepare the query with source filter
+ $query = $wpdb->prepare(
+ "DELETE FROM {$table_name} WHERE entry_id IN ({$placeholders}) AND source = %s",
+ array_merge($entry_ids, [$this->id])
+ );
+
+ $result = $wpdb->query($query);
+
+ if ($result === false) {
+ return new WP_REST_Response([
+ 'success' => false,
+ 'message' => __('Failed to delete entries', 'notificationx'),
+ ], 500);
+ }
+
+ return new WP_REST_Response([
+ 'success' => true,
+ 'message' => sprintf(
+ /* translators: %d: Number of entries deleted */
+ _n('%d entry deleted successfully', '%d entries deleted successfully', $result, 'notificationx'),
+ $result
+ ),
+ 'deleted_count' => $result,
+ ], 200);
+ }
+
+ /**
+ * Export feedback entries
+ *
+ * @param WP_REST_Request $request
+ * @return WP_REST_Response
+ */
+ public function export_feedback_entries($request) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . 'nx_entries';
+ $search = $request->get_param('s') ?: '';
+ $notification_id = $request->get_param('notification_id') ?: '';
+
+ // Build WHERE clause
+ $where_conditions = ["e.source = %s"];
+ $where_values = [$this->id];
+
+ // Add notification filter if provided
+ if (!empty($notification_id)) {
+ $where_conditions[] = "e.nx_id = %d";
+ $where_values[] = intval($notification_id);
+ }
+
+ // Add search functionality if provided
+ if (!empty($search)) {
+ $where_conditions[] = "(e.data LIKE %s OR e.created_at LIKE %s)";
+ $search_term = '%' . $wpdb->esc_like($search) . '%';
+ $where_values[] = $search_term;
+ $where_values[] = $search_term;
+ }
+
+ $where_clause = implode(' AND ', $where_conditions);
+
+ // Get all entries for export (no pagination)
+ $posts_table = $wpdb->prefix . 'nx_posts';
+ $query = $wpdb->prepare(
+ "SELECT e.entry_id, e.nx_id, e.data, e.created_at, p.title as notification_name
+ FROM {$table_name} e
+ LEFT JOIN {$posts_table} p ON e.nx_id = p.nx_id
+ WHERE {$where_clause}
+ ORDER BY e.created_at DESC",
+ ...$where_values
+ );
+
+ $entries = $wpdb->get_results($query, ARRAY_A);
+
+ if (empty($entries)) {
+ return new WP_REST_Response([
+ 'success' => false,
+ 'message' => __('No entries found to export', 'notificationx'),
+ ], 404);
+ }
+
+ // Generate CSV content
+ $csv_data = $this->generate_csv_data($entries);
+
+ // Generate filename
+ $filename = 'notificationx-feedback-entries-' . date('Y-m-d-H-i-s') . '.csv';
+
+ return new WP_REST_Response([
+ 'success' => true,
+ 'csv_content' => $csv_data,
+ 'filename' => $filename,
+ 'total_entries' => count($entries),
+ 'message' => sprintf(__('Successfully prepared %d entries for export', 'notificationx'), count($entries))
+ ], 200);
+ }
+
+ /**
+ * Generate CSV data from entries
+ *
+ * @param array $entries
+ * @return string
+ */
+ private function generate_csv_data($entries) {
+ $csv_data = [];
+ $is_pro = NotificationX::is_pro();
+
+ // CSV Headers
+ $csv_headers = [
+ __('No', 'notificationx'),
+ __('Date', 'notificationx'),
+ __('NotificationX Title', 'notificationx'),
+ ];
+
+ if ($is_pro) {
+ $csv_headers[] = __('Name', 'notificationx');
+ $csv_headers[] = __('Email Address', 'notificationx');
+ }
+
+ $csv_headers[] = __('Message', 'notificationx');
+
+ $csv_data[] = $csv_headers;
+
+ // Add data rows
+ $counter = 1;
+ foreach ($entries as $entry) {
+ $data = maybe_unserialize($entry['data']);
+ $date = new DateTime($entry['created_at']);
+
+ $row = [
+ $counter++,
+ $date->format('F j, Y'),
+ $entry['notification_name'] ?: sprintf(__('Notification #%d', 'notificationx'), $entry['nx_id']),
+ ];
+
+ if ($is_pro) {
+ $row[] = $data['name'] ?? '';
+ $row[] = $data['email'] ?? '';
+ }
+
+ $row[] = $data['message'] ?? '';
+
+ $csv_data[] = $row;
+ }
+
+ // Convert array to CSV string
+ $csv_content = '';
+ foreach ($csv_data as $row) {
+ $csv_content .= '"' . implode('","', array_map(function($field) {
+ return str_replace('"', '""', $field); // Escape quotes
+ }, $row)) . '"' . "n";
+ }
+
+ return $csv_content;
+ }
+}
No newline at end of file
--- a/notificationx/includes/Core/Rest/Posts.php
+++ b/notificationx/includes/Core/Rest/Posts.php
@@ -174,7 +174,31 @@
$query->offset($start_from)
->limit($per_page);
$posts = $query->get();
- $posts = PostType::get_instance()->__get_posts( $posts, '*' );
+ $posts = PostType::get_instance()->__get_posts( $posts, '*' );
+
+ // Add entries count for popup notifications
+ global $wpdb;
+ $entries_table = $wpdb->prefix . 'nx_entries';
+ $entries_counts = $wpdb->get_results(
+ "SELECT nx_id, COUNT(*) as entries_count
+ FROM {$entries_table}
+ WHERE source = 'popup_notification'
+ GROUP BY nx_id",
+ ARRAY_A
+ );
+
+ // Create a lookup array for entries counts
+ $entries_lookup = [];
+ foreach ($entries_counts as $entry) {
+ $entries_lookup[$entry['nx_id']] = $entry['entries_count'];
+ }
+
+ // Add entries count to posts
+ foreach ($posts as $key => $post) {
+ if ($post['source'] === 'popup_notification') {
+ $posts[$key]['entries'] = isset($entries_lookup[$post['nx_id']]) ? $entries_lookup[$post['nx_id']] : 0;
+ }
+ }
$total_posts = Database::get_instance()->get_post(Database::$table_posts, [], 'count(*) AS total');
$enabled = Database::get_instance()->get_post(Database::$table_posts, ['enabled' => true], 'count(*) AS total');
--- a/notificationx/includes/Extensions/ExtensionFactory.php
+++ b/notificationx/includes/Extensions/ExtensionFactory.php
@@ -59,7 +59,7 @@
'woocommerce' => 'NotificationXExtensionsWooCommerceWooCommerce',
'woocommerce_sales' => 'NotificationXExtensionsWooCommerceWooCommerceSales',
'woocommerce_sales_reviews' => 'NotificationXExtensionsWooCommerceWooCommerceSalesReviews',
- 'woocommerce_sales_inline' => 'NotificationXExtensionsWooCommerceWooCommerceSalesInline',
+ 'woocommerce_sales_inline' => 'NotificationXExtensionsWooCommerceWooCommerceSalesInline',
'woo_reviews' => 'NotificationXExtensionsWooCommerceWooReviews',
'wp_comments' => 'NotificationXExtensionsWordPressWPComments',
'wp_reviews' => 'NotificationXExtensionsWordPressWPOrgReview',
@@ -74,9 +74,10 @@
'vimeo' => 'NotificationXExtensionsVimeoVimeo',
'wistia' => 'NotificationXExtensionsWistiaWistia',
'surecart' => 'NotificationXExtensionsSureCartSureCart',
+ 'ActiveCampaign' => 'NotificationXExtensionsActiveCampaignActiveCampaign',
+ 'popup_notification' => 'NotificationXExtensionsPopupPopupNotification',
'fluentcart' => 'NotificationXExtensionsFluentCartFluentCart',
'fluentcart_inline' => 'NotificationXExtensionsFluentCartFluentCartInline',
- 'ActiveCampaign' => 'NotificationXExtensionsActiveCampaignActiveCampaign',
'gdpr_notification' => 'NotificationXExtensionsGDPRGDPR_Notification',
'ccpa_notification' => 'NotificationXExtensionsCCPACCPA_Notification',
];
--- a/notificationx/includes/Extensions/OfferAnnouncement/Announcements.php
+++ b/notificationx/includes/Extensions/OfferAnnouncement/Announcements.php
@@ -44,8 +44,8 @@
public function init_extension()
{
- $this->title = __('Discount Announcement', 'notificationx');
- $this->module_title = __('Discount Announcement', 'notificationx');
+ $this->title = __('Discount Alert', 'notificationx');
+ $this->module_title = __('Discount Alert', 'notificationx');
$this->themes = [
'theme-1' => [
'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/announcements/theme-1.png',
--- a/notificationx/includes/Extensions/PopupNotification/PopupNotification.php
+++ b/notificationx/includes/Extensions/PopupNotification/PopupNotification.php
@@ -0,0 +1,1001 @@
+<?php
+
+/**
+ * Popup Notification
+ *
+ * @package NotificationXExtensions
+ */
+
+namespace NotificationXExtensionsPopup;
+
+use NotificationXAdminInfoTooltipManager;
+use NotificationXCorePostType;
+use NotificationXGetInstance;
+use NotificationXCoreRules;
+use NotificationXExtensionsGlobalFields;
+use NotificationXExtensionsExtension;
+
+/**
+ * Popup Extension
+ * @method static Popup get_instance($args = null)
+ */
+class PopupNotification extends Extension {
+ /**
+ * Instance of Popup
+ *
+ * @var Popup
+ */
+ use GetInstance;
+
+ public $priority = 15;
+ public $id = 'popup_notification';
+ public $doc_link = 'https://notificationx.com/docs/how-to-show-announcement-using-notificationx/';
+ public $types = 'popup';
+ public $module = 'modules_popup';
+
+ /**
+ * Initially Invoked when initialized.
+ */
+ public function __construct(){
+ parent::__construct();
+ }
+
+ public function init() {
+ parent::init();
+ }
+
+ public function init_extension()
+ {
+ $this->title = __('Announcement', 'notificationx');
+ $this->module_title = __('Announcement', 'notificationx');
+ $this->themes = [
+ 'theme-one' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-one.png',
+ 'defaults' => [
+ 'popup_title' => __('Want to build credibility & boost sales?', 'notificationx'),
+ 'popup_content' => __('We help you optimize conversions & drive sales', 'notificationx'),
+ 'popup_button_text' => __('Get Started with Free Plan', 'notificationx'),
+ 'position' => 'center',
+ ],
+ 'column' => "5",
+ ],
+ 'theme-two' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-two.png',
+ 'defaults' => [
+ 'popup_title' => __('Boost your sales using SureCart', 'notificationx'),
+ 'popup_content' => __('<iframe width="560" height="315" src="https://www.youtube.com/embed/dw176Jmk74M?si=3suUqkCkQuYQrh2G" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>', 'notificationx'),
+ 'popup_button_text' => __('See How', 'notificationx'),
+ 'position' => 'center',
+ ],
+ 'column' => "5",
+ ],
+
+ 'theme-four' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-four.webp',
+ 'defaults' => [
+ 'popup_title' => __('Need Help?', 'notificationx'),
+ 'popup_content' => __('Get the latest news and updates delivered to your inbox.', 'notificationx'),
+ 'popup_button_text' => __('Submit', 'notificationx'),
+ 'position' => 'center',
+ ],
+ 'column' => "5",
+ ],
+ 'theme-five' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-five.webp',
+ 'defaults' => [
+ 'popup_title' => __('Need Help?', 'notificationx'),
+ 'popup_content' => __('Subscribe to receive exclusive offers and updates directly in your inbox.', 'notificationx'),
+ 'popup_email_placeholder' => __('Enter your email address', 'notificationx'),
+ 'popup_button_text' => __('Submit', 'notificationx'),
+ 'position' => 'center',
+ ],
+ 'is_pro' => true,
+ 'column' => "5",
+ ],
+ 'theme-seven' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-seven.webp',
+ 'defaults' => [
+ 'popup_title' => __('Want latest updates?', 'notificationx'),
+ 'popup_subtitle' => __('Would like to get the lastes news & updates instantly?', 'notificationx'),
+ 'popup_email_placeholder' => __('Enter email address', 'notificationx'),
+ 'popup_button_text' => __('Get In Touch', 'notificationx'),
+ 'popup_icon' => 'mail_icon.svg',
+ 'popup_button_icon' => 'mail_icon.svg',
+ 'position' => 'center',
+ ],
+ 'is_pro' => true,
+ 'column' => "5",
+ ],
+ 'theme-six' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-six.webp',
+ 'defaults' => [
+ 'popup_title' => __('Get latest news & updates', 'notificationx'),
+ 'popup_email_placeholder' => __('Your email address', 'notificationx'),
+ 'popup_button_text' => __('Submit Now', 'notificationx'),
+ 'position' => 'center',
+ ],
+ 'is_pro' => true,
+ 'column' => "5",
+ ],
+ 'theme-three' => [
+ 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-three.png',
+ 'defaults' => [
+ 'popup_title' => __('All Offers', 'notificationx'),
+ 'popup_button_text' => __('Latest Offers', 'notificationx'),
+ 'popup_button_icon' => 'latest_offer.svg',
+ 'position' => 'center',
+ ],
+ 'column' => "5",
+ ],
+
+ ];
+ }
+
+ public function init_fields() {
+ parent::init_fields();
+ add_filter('nx_design_tab_fields', [$this, 'design_fields'], 99);
+ add_filter('nx_content_fields', [$this, 'content_fields'], 999);
+ add_filter('nx_customize_fields', [$this, 'customize_fields'], 999);
+ add_filter('nx_display_fields', [$this, 'display_fields'], 999);
+ }
+
+ public function display_fields($fields) {
+ // Hide image selection
+ if (isset($fields['image-section'])) {
+ $fields['image-section'] = Rules::is('source', $this->id, true, $fields['image-section']);
+ }
+ return $fields;
+ }
+
+ public function design_fields( $fields ) {
+ if (isset($fields['advance_design_section']['fields']['design'])) {
+ $fields['advance_design_section']['fields']['design'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['design']);
+ }
+ if (isset($fields['advance_design_section']['fields']['typography'])) {
+ $fields['advance_design_section']['fields']['typography'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['typography']);
+ }
+ if (isset($fields['advance_design_section']['fields']['image-appearance'])) {
+ $fields['advance_design_section']['fields']['image-appearance'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['image-appearance']);
+ }
+ if (isset($fields['advance_design_section']['fields']['link_button_design'])) {
+ $fields['advance_design_section']['fields']['link_button_design'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['link_button_design']);
+ }
+
+ // Popup Container Design Section
+ $fields['advance_design_section']['fields']['popup_design'] = [
+ 'label' => __("Popup Design", 'notificationx'),
+ 'name' => "popup_design",
+ 'type' => "section",
+ 'priority' => 5,
+ 'rules' => Rules::logicalRule([
+ Rules::is('source', $this->id, false),
+ Rules::is('advance_edit', true),
+ ]),
+ 'fields' => [
+ [
+ 'label' => __("Background Color", 'notificationx'),
+ 'name' => "popup_bg_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Overlay Background Color", 'notificationx'),
+ 'name' => "overlay_color",
+ 'type' => "colorpicker",
+ 'help' => __('Background color of the overlay behind the popup', 'notificationx'),
+ ],
+ [
+ 'label' => __('Popup Width', 'notificationx'),
+ 'name' => "popup_width",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Maximum width of the popup container', 'notificationx'),
+ ],
+ [
+ 'label' => __('Border Radius', 'notificationx'),
+ 'name' => "popup_border_radius",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Rounded corners for the popup container', 'notificationx'),
+ ],
+ [
+ 'label' => __('Popup Padding', 'notificationx'),
+ 'name' => "popup_padding",
+ 'type' => "text",
+ 'help' => __('Internal spacing of popup content (e.g., 30px or 20px 30px)', 'notificationx'),
+ ],
+ [
+ 'label' => __("Close Button Color", 'notificationx'),
+ 'name' => "close_btn_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __('Close Button Size', 'notificationx'),
+ 'name' => "close_btn_size",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ ]
+ ];
+
+ // Typography Section
+ $fields['advance_design_section']['fields']['popup_typography'] = [
+ 'label' => __("Typography", 'notificationx'),
+ 'name' => "popup_typography",
+ 'type' => "section",
+ 'priority' => 6,
+ 'rules' => Rules::logicalRule([
+ Rules::is('source', $this->id, false),
+ Rules::is('advance_edit', true),
+ ]),
+ 'fields' => [
+ [
+ 'label' => __("Title Color", 'notificationx'),
+ 'name' => "popup_title_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __('Title Font Size', 'notificationx'),
+ 'name' => "popup_title_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Font size for the popup title', 'notificationx'),
+ ],
+ [
+ 'label' => __('Title Font Weight', 'notificationx'),
+ 'name' => "popup_title_font_weight",
+ 'type' => "select",
+ 'options' => GlobalFields::get_instance()->normalize_fields([
+ '300' => __('Light (300)', 'notificationx'),
+ '400' => __('Normal (400)', 'notificationx'),
+ '500' => __('Medium (500)', 'notificationx'),
+ '600' => __('Semi Bold (600)', 'notificationx'),
+ '700' => __('Bold (700)', 'notificationx'),
+ '800' => __('Extra Bold (800)', 'notificationx'),
+ ]),
+ ],
+ [
+ 'label' => __("Subtitle Color", 'notificationx'),
+ 'name' => "popup_subtitle_color",
+ 'type' => "colorpicker",
+ 'rules' => Rules::is('themes', 'popup_notification_theme-seven'),
+ ],
+ [
+ 'label' => __('Subtitle Font Size', 'notificationx'),
+ 'name' => "popup_subtitle_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Font size for the popup subtitle', 'notificationx'),
+ 'rules' => Rules::is('themes', 'popup_notification_theme-seven'),
+ ],
+ [
+ 'label' => __("Content/Message Color", 'notificationx'),
+ 'name' => "popup_content_color",
+ 'type' => "colorpicker",
+ 'rules' => Rules::logicalRule([
+ Rules::is('themes', 'popup_notification_theme-one'),
+ Rules::is('themes', 'popup_notification_theme-two'),
+ Rules::is('themes', 'popup_notification_theme-three'),
+ Rules::is('themes', 'popup_notification_theme-four'),
+ Rules::is('themes', 'popup_notification_theme-five'),
+ ], 'or'),
+ ],
+ [
+ 'label' => __('Content/Message Font Size', 'notificationx'),
+ 'name' => "popup_content_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Font size for the popup content/message text', 'notificationx'),
+ 'rules' => Rules::logicalRule([
+ Rules::is('themes', 'popup_notification_theme-one'),
+ Rules::is('themes', 'popup_notification_theme-two'),
+ Rules::is('themes', 'popup_notification_theme-three'),
+ Rules::is('themes', 'popup_notification_theme-four'),
+ Rules::is('themes', 'popup_notification_theme-five'),
+ ], 'or'),
+ ],
+ ]
+ ];
+
+ // Button Design Section
+ $fields['advance_design_section']['fields']['popup_button_design'] = [
+ 'label' => __("Button Design", 'notificationx'),
+ 'name' => "popup_button_design",
+ 'type' => "section",
+ 'priority' => 7,
+ 'rules' => Rules::logicalRule([
+ Rules::is('source', $this->id, false),
+ Rules::is('advance_edit', true),
+ ]),
+ 'fields' => [
+ [
+ 'label' => __("Background Color", 'notificationx'),
+ 'name' => "popup_button_bg_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Hover Background Color", 'notificationx'),
+ 'name' => "popup_button_hover_bg_color",
+ 'type' => "colorpicker",
+ 'help' => __('Background color when button is hovered', 'notificationx'),
+ ],
+ [
+ 'label' => __("Text Color", 'notificationx'),
+ 'name' => "popup_button_text_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Hover Text Color", 'notificationx'),
+ 'name' => "popup_button_hover_text_color",
+ 'type' => "colorpicker",
+ 'help' => __('Text color when button is hovered', 'notificationx'),
+ ],
+ [
+ 'label' => __("Border Color", 'notificationx'),
+ 'name' => "popup_button_border_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Hover Border Color", 'notificationx'),
+ 'name' => "popup_button_border_hover_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __('Border Width', 'notificationx'),
+ 'name' => "popup_button_border_width",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Width of the button border', 'notificationx'),
+ ],
+ [
+ 'label' => __('Font Size', 'notificationx'),
+ 'name' => "popup_button_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ [
+ 'label' => __('Font Weight', 'notificationx'),
+ 'name' => "popup_button_font_weight",
+ 'type' => "select",
+ 'options' => GlobalFields::get_instance()->normalize_fields([
+ '300' => __('Light (300)', 'notificationx'),
+ '400' => __('Normal (400)', 'notificationx'),
+ '500' => __('Medium (500)', 'notificationx'),
+ '600' => __('Semi Bold (600)', 'notificationx'),
+ '700' => __('Bold (700)', 'notificationx'),
+ ]),
+ ],
+ [
+ 'label' => __('Border Radius', 'notificationx'),
+ 'name' => "popup_button_border_radius",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Rounded corners for the button', 'notificationx'),
+ ],
+ [
+ 'label' => __('Padding', 'notificationx'),
+ 'name' => "popup_button_padding",
+ 'type' => "text",
+ 'help' => __('Button spacing in CSS format (e.g., 12px 24px)', 'notificationx'),
+ ],
+ [
+ 'label' => __('Button Width', 'notificationx'),
+ 'name' => "popup_button_width",
+ 'type' => "select",
+ 'default' => 'auto',
+ 'options' => GlobalFields::get_instance()->normalize_fields([
+ 'auto' => __('Auto Width', 'notificationx'),
+ '100%' => __('Full Width', 'notificationx'),
+ 'custom' => __('Custom Width', 'notificationx'),
+ ]),
+ ],
+ [
+ 'label' => __('Custom Button Width', 'notificationx'),
+ 'name' => "popup_button_custom_width",
+ 'type' => "number",
+ 'description' => 'px',
+ 'rules' => Rules::is('popup_button_width', 'custom'),
+ ],
+ ]
+ ];
+
+ // Email Input Design Section (for email collection themes)
+ $fields['advance_design_section']['fields']['popup_email_design'] = [
+ 'label' => __("Email Input Design", 'notificationx'),
+ 'name' => "popup_email_design",
+ 'type' => "section",
+ 'priority' => 8,
+ 'rules' => Rules::logicalRule([
+ Rules::is('source', $this->id, false),
+ Rules::is('advance_edit', true),
+ Rules::logicalRule([
+ Rules::is('themes', 'popup_notification_theme-five'),
+ Rules::is('themes', 'popup_notification_theme-six'),
+ Rules::is('themes', 'popup_notification_theme-seven'),
+ ], 'or'),
+ ]),
+ 'fields' => [
+ [
+ 'label' => __("Input Background Color", 'notificationx'),
+ 'name' => "popup_email_bg_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Input Text Color", 'notificationx'),
+ 'name' => "popup_email_text_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Input Border Color", 'notificationx'),
+ 'name' => "popup_email_border_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __("Input Focus Border Color", 'notificationx'),
+ 'name' => "popup_email_focus_border_color",
+ 'type' => "colorpicker",
+ 'help' => __('Border color when input is focused', 'notificationx'),
+ ],
+ [
+ 'label' => __("Placeholder Text Color", 'notificationx'),
+ 'name' => "popup_email_placeholder_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __('Input Font Size', 'notificationx'),
+ 'name' => "popup_email_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ [
+ 'label' => __('Input Border Width', 'notificationx'),
+ 'name' => "popup_email_border_width",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ [
+ 'label' => __('Input Border Radius', 'notificationx'),
+ 'name' => "popup_email_border_radius",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ [
+ 'label' => __('Input Padding', 'notificationx'),
+ 'name' => "popup_email_padding",
+ 'type' => "text",
+ 'help' => __('Input field spacing in CSS format (e.g., 12px 16px)', 'notificationx'),
+ ],
+ [
+ 'label' => __('Input Height', 'notificationx'),
+ 'name' => "popup_email_height",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Height of the email input field', 'notificationx'),
+ ],
+ ]
+ ];
+
+ // Repeater Items Design Section (for theme-three only)
+ $fields['advance_design_section']['fields']['popup_repeater_design'] = [
+ 'label' => __("Content Items Design", 'notificationx'),
+ 'name' => "popup_repeater_design",
+ 'type' => "section",
+ 'priority' => 9,
+ 'rules' => Rules::logicalRule([
+ Rules::is('source', $this->id, false),
+ Rules::is('advance_edit', true),
+ Rules::is('themes', 'popup_notification_theme-three'),
+ ]),
+ 'fields' => [
+ [
+ 'label' => __("Item Background Color", 'notificationx'),
+ 'name' => "popup_repeater_item_bg_color",
+ 'type' => "colorpicker",
+ 'help' => __('Background color for each content item', 'notificationx'),
+ ],
+ [
+ 'label' => __("Highlight Text Color", 'notificationx'),
+ 'name' => "popup_repeater_highlight_color",
+ 'type' => "colorpicker",
+ 'help' => __('Color for the highlight text (e.g., "30% OFF")', 'notificationx'),
+ ],
+ [
+ 'label' => __("Item Title Color", 'notificationx'),
+ 'name' => "popup_repeater_title_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __('Item Title Font Size', 'notificationx'),
+ 'name' => "popup_repeater_title_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ [
+ 'label' => __('Item Title Font Weight', 'notificationx'),
+ 'name' => "popup_repeater_title_font_weight",
+ 'type' => "select",
+ 'options' => GlobalFields::get_instance()->normalize_fields([
+ '400' => __('Normal (400)', 'notificationx'),
+ '500' => __('Medium (500)', 'notificationx'),
+ '600' => __('Semi Bold (600)', 'notificationx'),
+ '700' => __('Bold (700)', 'notificationx'),
+ ]),
+ ],
+ [
+ 'label' => __("Item Subtitle Color", 'notificationx'),
+ 'name' => "popup_repeater_subtitle_color",
+ 'type' => "colorpicker",
+ ],
+ [
+ 'label' => __('Item Subtitle Font Size', 'notificationx'),
+ 'name' => "popup_repeater_subtitle_font_size",
+ 'type' => "number",
+ 'description' => 'px',
+ ],
+ [
+ 'label' => __('Item Border Radius', 'notificationx'),
+ 'name' => "popup_repeater_item_border_radius",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Rounded corners for each content item', 'notificationx'),
+ ],
+ [
+ 'label' => __('Item Padding', 'notificationx'),
+ 'name' => "popup_repeater_item_padding",
+ 'type' => "text",
+ 'help' => __('Internal spacing for each content item (e.g., 16px)', 'notificationx'),
+ ],
+ [
+ 'label' => __('Item Spacing', 'notificationx'),
+ 'name' => "popup_repeater_item_spacing",
+ 'type' => "number",
+ 'description' => 'px',
+ 'help' => __('Space between content items', 'notificationx'),
+ ],
+ ]
+ ];
+
+ return $fields;
+ }
+
+ public function content_fields( $fields ) {
+ if (isset($fields['utm_options'])) {
+ $fields['utm_options'] = Rules::is('source', $this->id, true, $fields['utm_options']);
+ }
+ if (isset($fields['content'])) {
+ $fields['content'] = Rules::is('source', $this->id, true, $fields['content']);
+ }
+
+ $fields['popup_content'] = [
+ 'label' => __('Popup Content', 'notificationx'),
+ 'name' => 'popup_content',
+ 'type' => 'section',
+ 'priority' => 5,
+ 'rules' => Rules::is('source', $this->id),
+ 'fields' => [
+ [
+ 'label' => __('Title', 'notificationx'),
+ 'name' => 'popup_title',
+ 'type' => 'text',
+ 'priority' => 10,
+ 'default' => __('Special Offer!', 'notificationx'),
+ ],
+ [
+ 'label' => __('Subtitle', 'notificationx'),
+ 'name' => 'popup_subtitle',
+ 'type' => 'text'