__('Verify Certificate', 'academic-certificate-verification'), 'post_name' => $page_slug, 'post_content' => '[acceve_certificate_display]', 'post_status' => 'publish', 'post_type' => 'page', 'post_author' => get_current_user_id(), 'comment_status' => 'closed', 'ping_status' => 'closed', 'meta_input' => array( '_wp_page_template' => 'default' ) ); // Insert the page $page_id = wp_insert_post($page_data); // Store page ID in options for future reference if (!is_wp_error($page_id)) { update_option('acceve_certificate_verification_page_id', $page_id); } } else { // Update existing page with shortcode if needed if (false === strpos($page->post_content, '[acceve_certificate_display]')) { $page_data = array( 'ID' => $page->ID, 'post_content' => $page->post_content . "\n[acceve_certificate_display]" ); wp_update_post($page_data); } // Store page ID in options update_option('acceve_certificate_verification_page_id', $page->ID); } } /** * Add admin menu pages. * * Creates the main menu and submenu items in WordPress admin. * * @since 1.0.0 * * @return void */ public function add_admin_menu() { add_menu_page( __('Certificate Verification', 'academic-certificate-verification'), __('Certificates', 'academic-certificate-verification'), 'manage_options', 'certificate_verification', array($this, 'admin_dashboard'), 'dashicons-awards', 30 ); add_submenu_page( 'certificate_verification', __('All Certificates', 'academic-certificate-verification'), __('All Certificates', 'academic-certificate-verification'), 'manage_options', 'certificate_verification', array($this, 'admin_dashboard') ); add_submenu_page( 'certificate_verification', __('Add New Certificate', 'academic-certificate-verification'), __('Add New', 'academic-certificate-verification'), 'manage_options', 'certificate_verification_add', array($this, 'add_certificate_page') ); add_submenu_page( 'certificate_verification', __('Import Certificates', 'academic-certificate-verification'), __('Import', 'academic-certificate-verification'), 'manage_options', 'certificate_verification_import', array($this, 'import_certificates_page') ); add_submenu_page( 'certificate_verification', __('Custom Fields', 'academic-certificate-verification'), __('Custom Fields', 'academic-certificate-verification'), 'manage_options', 'manage_custom_fields', array($this, 'manage_custom_fields_page') ); add_submenu_page( 'certificate_verification', __('Add Courses', 'academic-certificate-verification'), __('Add Courses', 'academic-certificate-verification'), 'manage_options', 'manage_add_courses', array($this, 'manage_add_courses_page') ); add_submenu_page( 'certificate_verification', __('Add Batches', 'academic-certificate-verification'), __('Add Batches', 'academic-certificate-verification'), 'manage_options', 'manage_add_batches', array($this, 'manage_add_batches_page') ); add_submenu_page( 'certificate_verification', __('Certificate Maker', 'academic-certificate-verification'), __('Certificate Maker', 'academic-certificate-verification'), 'manage_options', 'certificate_maker', array($this, 'certificate_maker_page') ); add_submenu_page( 'certificate_verification', __('Settings', 'academic-certificate-verification'), __('Settings', 'academic-certificate-verification'), 'manage_options', 'certificate_verification_settings', array($this, 'settings_page') ); add_submenu_page( 'certificate_verification', __('Upgrade Pro', 'academic-certificate-verification'), __('Upgrade Pro', 'academic-certificate-verification'), 'manage_options', 'certificate_verification_pro', array($this, 'upgrade_pro_page') ); } /** * Register plugin settings. * * Registers settings, sections, and fields for the plugin. * * @since 1.0.0 * * @return void */ public function register_settings() { register_setting( 'certificate_verification_settings', 'acceve_certificate_verification_options', array( 'type' => 'array', 'sanitize_callback' => array($this, 'acceve_sanitize_settings'), 'default' => array( 'default_institution' => '', 'certificate_prefix' => '', 'certificate_template' => 'template_one' ) ) ); add_settings_section( 'general_settings', __('General Settings', 'academic-certificate-verification'), array($this, 'general_settings_section_callback'), 'certificate_verification_settings' ); add_settings_field( 'default_institution', __('Default Institution', 'academic-certificate-verification'), array($this, 'default_institution_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'certificate_prefix', __('Certificate ID Prefix', 'academic-certificate-verification'), array($this, 'certificate_prefix_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'date_format', __('Date Format', 'academic-certificate-verification'), array($this, 'date_format_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'certificate_template', __('Certificate Template', 'academic-certificate-verification'), array($this, 'certificate_template_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_certificate_share', __('Enable Certificate Share', 'academic-certificate-verification'), array($this, 'enable_certificate_share_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_qr_code', __('Enable QR Code', 'academic-certificate-verification'), array($this, 'enable_qr_code_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_barcode', __('Enable Barcode', 'academic-certificate-verification'), array($this, 'enable_barcode_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_date_of_birth', __('Enable Date of Birth for Certificate Verification', 'academic-certificate-verification'), array($this, 'enable_date_of_birth_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_issue_date', __('Enable Certificate Issue Date for Certificate Verification', 'academic-certificate-verification'), array($this, 'enable_issue_date_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_download_button', __('Enable Download Button', 'academic-certificate-verification'), array($this, 'enable_download_button_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'enable_download_button_verify_page', __('Enable Download Button on Verify Page', 'academic-certificate-verification'), array($this, 'enable_download_button_verify_page_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'download_button_bg', __('Verification form Button Background Color', 'academic-certificate-verification'), array($this, 'download_button_bg_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'download_button_text', __('Verification form Button Text Color', 'academic-certificate-verification'), array($this, 'download_button_text_callback'), 'certificate_verification_settings', 'general_settings' ); add_settings_field( 'verification_message', __('Verification Message', 'academic-certificate-verification'), array($this, 'verification_message_callback'), 'certificate_verification_settings', 'general_settings' ); $this->register_filter_settings(); $this->register_text_label_settings(); } /** * General settings section callback. * * Displays description for the general settings section. * * @since 1.0.0 * * @return void */ public function general_settings_section_callback() { echo '
' . esc_html__('Configure general settings for the certificate verification system.', 'academic-certificate-verification') . '
'; } /** * Default institution field callback. * * Renders the default institution input field. * * @since 1.0.0 * * @return void */ public function default_institution_callback() { $options = get_option('acceve_certificate_verification_options'); echo ''; } /** * Certificate prefix field callback. * * Renders the certificate ID prefix input field. * * @since 1.0.0 * * @return void */ public function certificate_prefix_callback() { $options = get_option('acceve_certificate_verification_options'); $prefix = isset($options['certificate_prefix']) ? $options['certificate_prefix'] : ''; echo ''; echo '' . esc_html__('This will be prepended to auto-generated certificate IDs.', 'academic-certificate-verification') . '
'; } /** * Date format field callback. * * Renders WordPress-style Date Format option choices with preview. * * @since 1.0.11 * * @return void */ public function date_format_callback() { $options = get_option('acceve_certificate_verification_options'); $format_val = !empty($options['date_format']) ? $options['date_format'] : 'd/m/Y'; $choice_val = !empty($options['date_format_choice']) ? $options['date_format_choice'] : (in_array($format_val, array('F j, Y', 'Y-m-d', 'm/d/Y', 'd/m/Y', 'd.m.Y'), true) ? $format_val : 'custom'); // Sample date: August 5, 2026 $sample_ts = strtotime('2026-08-05'); $date_formats = array( 'F j, Y' => date_i18n('F j, Y', $sample_ts), 'Y-m-d' => date_i18n('Y-m-d', $sample_ts), 'm/d/Y' => date_i18n('m/d/Y', $sample_ts), 'd/m/Y' => date_i18n('d/m/Y', $sample_ts), 'd.m.Y' => date_i18n('d.m.Y', $sample_ts), ); ?> is_license_active(); // Get certificate templates from database if pro version is active $certificate_templates = array(); if ($is_pro) { global $wpdb; $table_name = $wpdb->prefix . 'acceve_certificate_templates'; // phpcs:ignore if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) == $table_name) {$certificate_templates = $wpdb->get_results("SELECT id, template_name FROM {$table_name} ORDER BY template_name ASC", ARRAY_A);} } ?>is_license_active(); ?> PRO is_license_active(); ?> PRO is_license_active(); ?> PRO is_license_active(); ?> PRO is_license_active(); ?> PRO is_license_active(); ?> PRO is_license_active(); ?> PRO is_license_active(); ?> PRO name="acceve_certificate_verification_options[download_button_bg_color]" value="" data-default-color="#2271b1">
is_license_active(); ?> PRO name="acceve_certificate_verification_options[download_button_text_color]" value="" data-default-color="#ffffff">
is_license_active(); ?> PRO
{institution},
{issue_date},
{certificate_id},
{student_name}
' . esc_html__('Shortcode:', 'academic-certificate-verification') . ' [acceve_certificate_filter]
' . esc_html__('Select which fields to use for filtering certificates.', 'academic-certificate-verification') . '
'; } /** * Filter layout callback */ public function filter_layout_callback() { $options = get_option('acceve_certificate_verification_options'); $layout = isset($options['filter_layout']) ? $options['filter_layout'] : 'grid'; $license_handler = ACCEVE_License_Handler::get_instance(); $is_active = $license_handler->is_license_active(); ?> PRO 'label_form_heading', 'title' => __('Verification form heading', 'academic-certificate-verification'), 'description' => __('Default: Verify Certificate', 'academic-certificate-verification'), ), array( 'id' => 'label_certificate_id', 'title' => __('Certificate ID field label', 'academic-certificate-verification'), 'description' => __('Default: Certificate ID', 'academic-certificate-verification'), ), array( 'id' => 'label_date_of_birth', 'title' => __('Date of birth field label', 'academic-certificate-verification'), 'description' => __('Default: Date of Birth', 'academic-certificate-verification'), ), array( 'id' => 'label_issue_date', 'title' => __('Certificate issue date field label', 'academic-certificate-verification'), 'description' => __('Default: Certificate Issue Date', 'academic-certificate-verification'), ), array( 'id' => 'certificate_verified_successful_message', 'title' => __('Certificate Verified Successful Message', 'academic-certificate-verification'), 'description' => __('Default: Certificate Verified Successfully!', 'academic-certificate-verification'), ), array( 'id' => 'label_verify_button', 'title' => __('Verify button text', 'academic-certificate-verification'), 'description' => __('Default: Verify Certificate', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_heading', 'title' => __('Certificate filter heading', 'academic-certificate-verification'), 'description' => __('Used by the filter shortcode (Pro). Default: Filter Certificates', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_button', 'title' => __('Certificate filter submit button', 'academic-certificate-verification'), 'description' => __('Default: Filter', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_reset', 'title' => __('Certificate filter reset button', 'academic-certificate-verification'), 'description' => __('Default: Reset', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_all_option', 'title' => __('Filter dropdown "All" option', 'academic-certificate-verification'), 'description' => __('Default: All', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_loading', 'title' => __('Filter loading text', 'academic-certificate-verification'), 'description' => __('Default: Loading...', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_no_results', 'title' => __('Filter no results message', 'academic-certificate-verification'), 'description' => __('Default: No certificates found matching your criteria.', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_disabled', 'title' => __('Message when filtering is disabled', 'academic-certificate-verification'), 'description' => __('Default: Certificate filtering is currently disabled.', 'academic-certificate-verification'), ), array( 'id' => 'label_filter_no_fields', 'title' => __('Message when no filter fields are configured', 'academic-certificate-verification'), 'description' => __('Default: No filter fields configured.', 'academic-certificate-verification'), ), ); foreach ($labels as $field) { add_settings_field( $field['id'], $field['title'], array($this, 'text_label_input_callback'), 'certificate_verification_settings', 'text_label_settings', array( 'name' => $field['id'], 'description' => $field['description'], ) ); } } /** * Text label settings section description. * * @return void */ public function text_label_settings_section_callback() { echo '' . esc_html__('Customize text shown on the verification form and certificate filter (Pro). Leave a field empty to use the default.', 'academic-certificate-verification') . '
'; } /** * Generic text input for label overrides. * * @param array $args Field arguments. * * @return void */ public function text_label_input_callback( $args ) { $options = get_option('acceve_certificate_verification_options'); $name = isset($args['name']) ? $args['name'] : ''; $value = ( $name && isset($options[ $name ]) ) ? $options[ $name ] : ''; ?> '; do_settings_fields($page, $section_id); echo ''; } /** * Sanitize settings callback. * * Sanitizes and validates plugin settings before saving. * * @since 1.0.0 * * @param array $input The input values from the form. * * @return array Sanitized values. */ public function acceve_sanitize_settings($input) { if (!is_array($input)) { $input = array(); } $previous = get_option('acceve_certificate_verification_options', array()); $sanitized = is_array($previous) ? $previous : array(); if (isset($input['default_institution'])) { $sanitized['default_institution'] = sanitize_text_field($input['default_institution']); } if (isset($input['certificate_prefix'])) { $sanitized['certificate_prefix'] = preg_replace('/[^A-Za-z0-9\-]/', '', $input['certificate_prefix']); } if (isset($input['date_format_choice'])) { $choice = sanitize_text_field($input['date_format_choice']); $sanitized['date_format_choice'] = $choice; if ($choice === 'custom') { $custom_fmt = !empty($input['date_format_custom']) ? sanitize_text_field($input['date_format_custom']) : 'd/m/Y'; $sanitized['date_format'] = $custom_fmt; } else { $sanitized['date_format'] = $choice; } } if (isset($input['certificate_template'])) { $allowed_templates = array('template_one', 'template_two', 'custom_template'); $sanitized['certificate_template'] = in_array($input['certificate_template'], $allowed_templates) ? $input['certificate_template'] : 'template_one'; // Only save custom template ID if custom_template is selected if ($input['certificate_template'] === 'custom_template' && isset($input['certificate_custom_template'])) { $sanitized['certificate_custom_template'] = intval($input['certificate_custom_template']); } } // NEW: Download button settings $sanitized['enable_date_of_birth'] = isset($input['enable_date_of_birth']) ? 1 : 0; $sanitized['enable_issue_date'] = isset($input['enable_issue_date']) ? 1 : 0; $sanitized['enable_download_button'] = isset($input['enable_download_button']) ? 1 : 0; $sanitized['enable_download_button_verify_page'] = isset($input['enable_download_button_verify_page']) ? 1 : 0; $sanitized['enable_certificate_share'] = isset($input['enable_certificate_share']) ? 1 : 0; $sanitized['enable_qr_code'] = isset($input['enable_qr_code']) ? 1 : 0; $sanitized['enable_barcode'] = isset($input['enable_barcode']) ? 1 : 0; if (isset($input['download_button_bg_color'])) { $sanitized['download_button_bg_color'] = sanitize_hex_color($input['download_button_bg_color']); } if (isset($input['download_button_text_color'])) { $sanitized['download_button_text_color'] = sanitize_hex_color($input['download_button_text_color']); } if (isset($input['verification_message'])) { $sanitized['verification_message'] = sanitize_textarea_field($input['verification_message']); } // NEW: Filter settings sanitization $sanitized['filter_enabled'] = isset($input['filter_enabled']) ? 1 : 0; if (isset($input['filter_fields']) && is_array($input['filter_fields'])) { $sanitized['filter_fields'] = array_map('sanitize_text_field', $input['filter_fields']); } else { $sanitized['filter_fields'] = array(); } if (isset($input['filter_layout'])) { $sanitized['filter_layout'] = in_array($input['filter_layout'], array('grid', 'list')) ? $input['filter_layout'] : 'grid'; } $label_keys = array( 'label_form_heading', 'label_certificate_id', 'label_date_of_birth', 'label_issue_date', 'certificate_verified_successful_message', 'label_verify_button', 'label_filter_heading', 'label_filter_button', 'label_filter_reset', 'label_filter_all_option', 'label_filter_loading', 'label_filter_no_results', 'label_filter_disabled', 'label_filter_no_fields', ); foreach ($label_keys as $label_key) { if (array_key_exists($label_key, $input)) { $sanitized[ $label_key ] = sanitize_text_field($input[ $label_key ]); } } return $sanitized; } /** * Admin dashboard page. * * Displays the main certificates listing with statistics. * * @since 1.0.0 * * @return void */ public function admin_dashboard() { if (!class_exists('WP_List_Table')) { require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; } require_once ACCEVE_PATH . 'includes/class-certificates-list-table.php'; // Create an instance of our custom list table $certificates_table = new ACCEVE_Certificates_List_Table(); $certificates_table->prepare_items(); $total_certificates = $this->get_certificate_count(); $active_certificates = $this->get_certificate_count('active'); $expired_certificates = $this->get_certificate_count('expired'); include ACCEVE_PATH . 'templates/admin/dashboard.php'; } /** * Get certificate count by status. * * Retrieves the count of certificates based on status. * * @since 1.0.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $status The status to filter by: 'all', 'active', or 'expired'. * * @return int Number of certificates. */ private function get_certificate_count($status = 'all') { global $wpdb; $table_name = $wpdb->prefix . 'acceve_certificate_verification'; $query = "SELECT COUNT(*) FROM $table_name"; switch ($status) { case 'active': $query .= " WHERE is_active = 1 AND (expiry_date IS NULL OR expiry_date >= CURDATE())"; break; case 'expired': $query .= " WHERE (expiry_date IS NOT NULL AND expiry_date < CURDATE()) OR is_active = 0"; break; } // phpcs:ignore return $wpdb->get_var($query); } /** * Add/Edit certificate page. * * Displays the form for adding or editing a certificate. * * @since 1.0.0 * * @return void */ public function add_certificate_page() { $certificate = null; // Check if this is an edit request if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['certificate_id'])) { $db = ACCEVE_Certificate_Verification_Database::get_instance(); // phpcs:ignore $certificate = $db->get_certificate(sanitize_text_field(wp_unslash($_GET['certificate_id']))); if (!$certificate) { wp_die(esc_html__('Certificate not found.', 'academic-certificate-verification')); } } // phpcs:ignore if ($_SERVER['REQUEST_METHOD'] === 'POST' && check_admin_referer('add_certificate')) { $this->process_add_certificate(); } include ACCEVE_PATH . 'templates/admin/add-certificate.php'; } /** * Process add/edit certificate form submission. * * Handles the submission of the certificate form for both * adding new certificates and editing existing ones. * Save custom fields data when certificate is saved * * @since 1.0.0 * * @return void */ public function process_add_certificate() { // Verify nonce if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'add_certificate')) { wp_die(esc_html__('Security check failed.', 'academic-certificate-verification')); } // Check user capabilities if (!current_user_can('manage_options')) { wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'academic-certificate-verification')); } // Prepare certificate data - START WITH BASIC FIELDS $data = array( 'certificate_id' => isset($_POST['certificate_id']) ? sanitize_text_field(wp_unslash($_POST['certificate_id'])) : '', 'student_name' => isset($_POST['student_name']) ? sanitize_text_field(wp_unslash($_POST['student_name'])) : '', 'birth_date' => isset($_POST['birth_date']) ? sanitize_text_field(wp_unslash($_POST['birth_date'])) : '0000-00-00', 'course_type' => isset($_POST['course_type']) ? sanitize_text_field(wp_unslash($_POST['course_type'])) : '', 'course_name' => isset($_POST['course_name']) ? sanitize_text_field(wp_unslash($_POST['course_name'])) : '', 'batch_name' => isset($_POST['batch_name']) ? sanitize_text_field(wp_unslash($_POST['batch_name'])) : '', 'institution' => isset($_POST['institution']) ? sanitize_text_field(wp_unslash($_POST['institution'])) : '', 'issue_date' => isset($_POST['issue_date']) ? sanitize_text_field(wp_unslash($_POST['issue_date'])) : '', 'is_active' => 1 ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if (isset($_POST['custom_fields']) && is_array($_POST['custom_fields'])) { $field_definitions = $this->get_custom_field_definitions_indexed(); $custom_fields_data = array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $custom_fields_input = wp_unslash($_POST['custom_fields']); foreach ($custom_fields_input as $field_name => $field_value) { $sanitized_field_name = sanitize_key($field_name); $field_type = isset($field_definitions[$sanitized_field_name]) ? $field_definitions[$sanitized_field_name]->field_type : 'text'; // Sanitize based on type if (is_array($field_value)) { // For checkboxes - store as comma-separated string $sanitized_values = array_map('sanitize_text_field', $field_value); $custom_fields_data[$sanitized_field_name] = implode(',', $sanitized_values); } else { if ($field_type === 'image') { $custom_fields_data[$sanitized_field_name] = esc_url_raw(wp_unslash($field_value)); } else { $custom_fields_data[$sanitized_field_name] = sanitize_text_field(wp_unslash($field_value)); } } } $data['custom_fields'] = wp_json_encode($custom_fields_data); } else { // If no custom fields are submitted, set to empty JSON $data['custom_fields'] = wp_json_encode(array()); } // Handle optional fields if (!empty($_POST['expiry_date'])) { $data['expiry_date'] = sanitize_text_field(wp_unslash($_POST['expiry_date'])); } else { $data['expiry_date'] = null; } if (!empty($_POST['additional_data'])) { $data['additional_data'] = sanitize_textarea_field(wp_unslash($_POST['additional_data'])); } if (!empty($_POST['course_id'])) { $data['course_id'] = sanitize_textarea_field(wp_unslash($_POST['course_id'])); } // Per-certificate QR code & barcode content (Pro feature). Always set so // editing can clear a previously stored value. $data['qr_content'] = isset($_POST['qr_content']) ? sanitize_text_field(wp_unslash($_POST['qr_content'])) : ''; $data['barcode_content'] = isset($_POST['barcode_content']) ? sanitize_text_field(wp_unslash($_POST['barcode_content'])) : ''; $db = ACCEVE_Certificate_Verification_Database::get_instance(); // Check if this is an update if (!empty($_POST['original_certificate_id'])) { $original_id = sanitize_text_field(wp_unslash($_POST['original_certificate_id'])); $result = $db->update_certificate($original_id, $data); } else { // New certificate $options = get_option('acceve_certificate_verification_options'); $data['verification_code'] = wp_generate_password(8, false); $result = $db->add_certificate($data); } // Handle result if ($result) { wp_safe_redirect(admin_url('admin.php?page=certificate_verification&updated=1')); exit; } else { $error = __('Error saving certificate.', 'academic-certificate-verification'); if (!empty($_POST['original_certificate_id'])) { // phpcs:ignore wp_safe_redirect(admin_url('admin.php?page=certificate_verification_add&action=edit&certificate_id=' . urlencode($_POST['original_certificate_id']) . '&error=' . urlencode($error))); } else { wp_safe_redirect(admin_url('admin.php?page=certificate_verification_add&error=' . urlencode($error))); } exit; } } /** * Import certificates page. * * Displays the import certificates interface. * * @since 1.0.0 * * @return void */ public function import_certificates_page() { include ACCEVE_PATH . 'templates/admin/import-certificates.php'; } /** * Handle certificate actions. * * Processes certificate actions like delete from URL parameters. * * @since 1.0.0 * * @return void */ public function handle_certificate_actions() { // phpcs:ignore if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['certificate_id'])) { $this->delete_certificate(); } } /** * Delete a single certificate. * * Handles deletion of individual certificates with security checks. * * @since 1.0.0 * * @return void */ private function delete_certificate() { if (!isset($_GET['certificate_id']) || !isset($_GET['_wpnonce'])) { wp_die(esc_html__('Invalid request.', 'academic-certificate-verification')); } $certificate_id = sanitize_text_field(wp_unslash($_GET['certificate_id'])); $nonce = sanitize_text_field(wp_unslash($_GET['_wpnonce'])); // Verify nonce if (!wp_verify_nonce($nonce, 'delete_certificate_' . $certificate_id)) { wp_die(esc_html__('Security check failed.', 'academic-certificate-verification')); } $db = ACCEVE_Certificate_Verification_Database::get_instance(); $result = $db->delete_certificate($certificate_id); if ($result) { wp_safe_redirect(admin_url('admin.php?page=certificate_verification&deleted=1')); exit; } else { wp_safe_redirect(admin_url('admin.php?page=certificate_verification&deleted=0')); exit; } } /** * Settings page. * * Displays the plugin settings page. * * @since 1.0.0 * * @return void */ public function settings_page() { include ACCEVE_PATH . 'templates/admin/settings.php'; } /** * Upgrade Pro page. * * Displays the Pro version upgrade page with features and contact information. * * @since 1.0.0 * * @return void */ public function upgrade_pro_page() { // Security check if (!current_user_can('manage_options')) { wp_die(esc_html__('You do not have sufficient permissions.', 'academic-certificate-verification')); } // Get license handler $license_handler = ACCEVE_License_Handler::get_instance(); $license_info = $license_handler->get_license_info(); $is_active = $license_handler->is_license_active(); ?>