prefix and fixed strings, and every // value goes through $wpdb->prepare() or $wpdb->insert/update/delete. // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching class Certificates { public static function init() { add_action( 'init', array( __CLASS__, 'register_rewrite' ) ); add_action( 'template_redirect', array( __CLASS__, 'handle_certificate_view' ) ); } public static function register_rewrite() { add_rewrite_rule( '^certificate/([a-zA-Z0-9]+)/?$', 'index.php?accessnow_slms_certificate=$matches[1]', 'top' ); add_rewrite_tag( '%accessnow_slms_certificate%', '([a-zA-Z0-9]+)' ); } public static function handle_certificate_view() { $code = get_query_var( 'accessnow_slms_certificate' ); if ( ! $code ) { return; } $cert = self::get_by_code( $code ); if ( ! $cert || ! get_userdata( $cert->user_id ) || ! get_post( $cert->course_id ) ) { wp_die( esc_html__( 'Certificate not found.', 'accessnow-lms' ), 404 ); } // The certificate is a standalone page (no theme header/footer), so its // assets are printed directly by the template. wp_register_style( 'slms-certificate', ACCESSNOW_SLMS_PLUGIN_URL . 'assets/css/slms-certificate.css', array(), ACCESSNOW_SLMS_VERSION ); wp_register_script( 'slms-certificate', ACCESSNOW_SLMS_PLUGIN_URL . 'assets/js/slms-certificate.js', array(), ACCESSNOW_SLMS_VERSION, true ); $template = locate_template( 'single-slms_certificate.php' ); if ( ! $template ) { $template = ACCESSNOW_SLMS_PLUGIN_DIR . 'templates/single-slms_certificate.php'; } /** * The template a certificate page is rendered from: the theme's single-slms_certificate.php, * else the plugin's. The template prints its own assets (slms-certificate is registered). * * @since 1.1.0 * * @param string $template Full path. * @param object $cert Certificate row (user_id, course_id, certificate_code, issued_at...). */ $template = apply_filters( 'accessnow_slms_certificate_template', $template, $cert ); include is_string( $template ) && file_exists( $template ) ? $template : ACCESSNOW_SLMS_PLUGIN_DIR . 'templates/single-slms_certificate.php'; exit; } public static function issue( $user_id, $course_id, $enrollment_id = 0 ) { global $wpdb; $table = $wpdb->prefix . 'slms_certificates'; $existing = self::get_for_enrollment( $enrollment_id, $course_id ); if ( $existing ) { return $existing; } $code = wp_generate_password( 16, false ); $wpdb->insert( $table, array( 'user_id' => $user_id, 'course_id' => $course_id, 'enrollment_id' => $enrollment_id, 'certificate_code' => $code, 'issued_at' => current_time( 'mysql', true ), ), array( '%d', '%d', '%d', '%s', '%s' ) ); $certificate = self::get_by_code( $code ); if ( $certificate ) { /** * A certificate was issued (once per enrolment; a reopened enrolment keeps its certificate). * * @since 1.0.0 * * @param object $certificate Certificate row (certificate_code, issued_at, ...). * @param int $user_id User ID. * @param int $course_id Course ID. * @param int $enrollment_id Enrolment ID. */ do_action( 'accessnow_slms_certificate_issued', $certificate, (int) $user_id, (int) $course_id, (int) $enrollment_id ); } return $certificate; } /** * The certificate already issued for an enrolment, if any. * * @param int $enrollment_id Enrolment ID. * @param int $course_id Course ID. * @return object|null */ public static function get_for_enrollment( $enrollment_id, $course_id ) { global $wpdb; return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}slms_certificates WHERE enrollment_id = %d AND course_id = %d", $enrollment_id, $course_id ) ); } public static function get_by_code( $code ) { global $wpdb; return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}slms_certificates WHERE certificate_code = %s", $code ) ); } public static function get_user_certificates( $user_id ) { global $wpdb; return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}slms_certificates WHERE user_id = %d ORDER BY issued_at DESC", $user_id ) ); } public static function get_certificate_url( $code ) { return home_url( 'certificate/' . $code ); } }