enqueue_assets(); $form_template_path = AARAMBHA_CASE_MANAGEMENT_PATH . 'includes/Frontend/Templates/form.php'; if ( ! file_exists( $form_template_path ) ) { return ''; } ob_start(); // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable -- Path is built from a hardcoded internal constant and literal filename, never user input. include $form_template_path; return ob_get_clean(); } /** * Handle form submission. * * @return void */ public function handle_submission(): void { // Only process POST requests. if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) { return; } // Check our submit button. if ( ! isset( $_POST['aarambha_case_management_submit_case'] ) ) { return; } // Verify nonce. if ( ! isset( $_POST['aarambha_case_management_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['aarambha_case_management_nonce'] ) ), 'aarambha_case_management_submit_case' ) ) { wp_die( esc_html__( 'Security check failed.', 'aarambha-case-management' ) ); } if ( ! $this->validate() ) { return; } $repository = new CaseRepository(); $data = [ 'customer_name' => $this->values['aarambha_case_management_name'], 'customer_email' => $this->values['aarambha_case_management_email'], 'phone' => $this->values['aarambha_case_management_phone'], 'subject' => $this->values['aarambha_case_management_subject'], 'description' => $this->values['aarambha_case_management_description'], ]; $result = $repository->create( $data ); if ( empty( $result ) ) { wp_die( esc_html__( 'Unable to create the case. Please try again.', 'aarambha-case-management' ) ); } // Upload files. if ( ! empty( $_FILES['aarambha_case_management_attachments']['name'][0] ) ) { $uploader = new FileUploader(); try { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- $_FILES is a server-populated superglobal, not raw user text; FileUploader::upload() is responsible for validating file type/size before use. $attachment_ids = $uploader->upload( $_FILES['aarambha_case_management_attachments'] ); } catch ( \RuntimeException $e ) { $this->errors['aarambha_case_management_attachments'] = $e->getMessage(); return; } // Save the file relationships. $file_repository = new FileRepository(); foreach ( $attachment_ids as $attachment_id ) { $file_repository->save( $result['id'], $attachment_id ); } } $case = $repository->find( $result['id'] ); $mailer = new Mailer(); // Email confirmation to customer. $mailer->send_case_confirmation( $case ); // Email notification to admin. $mailer->send_new_case_notification( $case ); $this->redirect_success( $result['case_number'] ); } /** * Redirect after successful submission. * * @param string $case_number Case reference. * @return void */ private function redirect_success( string $case_number ): void { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Optional redirect target read from the same already-nonce-verified submission handled in handle_submission(); falls back to home_url() if absent. $redirect = isset( $_POST['aarambha_case_management_redirect'] ) ? esc_url_raw( wp_unslash( $_POST['aarambha_case_management_redirect'] ) ) : home_url(); $url = add_query_arg( [ 'aarambha_case_management_success' => 1, 'case' => $case_number, ], $redirect ); wp_safe_redirect( $url ); exit; } /** * Validate form input. * * Note: nonce verification for this POST data is already performed in * handle_submission() before this method is called. * * @return bool */ private function validate(): bool { $this->errors = []; // phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce already verified in handle_submission() before validate() is called. $this->values = [ 'aarambha_case_management_name' => sanitize_text_field( wp_unslash( $_POST['aarambha_case_management_name'] ?? '' ) ), 'aarambha_case_management_email' => sanitize_email( wp_unslash( $_POST['aarambha_case_management_email'] ?? '' ) ), 'aarambha_case_management_phone' => sanitize_text_field( wp_unslash( $_POST['aarambha_case_management_phone'] ?? '' ) ), 'aarambha_case_management_subject' => sanitize_text_field( wp_unslash( $_POST['aarambha_case_management_subject'] ?? '' ) ), 'aarambha_case_management_description' => sanitize_textarea_field( wp_unslash( $_POST['aarambha_case_management_description'] ?? '' ) ), ]; // phpcs:enable if ( '' === $this->values['aarambha_case_management_name'] ) { $this->errors['aarambha_case_management_name'] = __( 'Full name is required.', 'aarambha-case-management' ); } if ( '' === $this->values['aarambha_case_management_email'] ) { $this->errors['aarambha_case_management_email'] = __( 'Email address is required.', 'aarambha-case-management' ); } elseif ( ! is_email( $this->values['aarambha_case_management_email'] ) ) { $this->errors['aarambha_case_management_email'] = __( 'Please enter a valid email address.', 'aarambha-case-management' ); } if ( '' === $this->values['aarambha_case_management_phone'] ) { $this->errors['aarambha_case_management_phone'] = __( 'Phone is required.', 'aarambha-case-management' ); } if ( '' === $this->values['aarambha_case_management_subject'] ) { $this->errors['aarambha_case_management_subject'] = __( 'Subject is required.', 'aarambha-case-management' ); } if ( '' === $this->values['aarambha_case_management_description'] ) { $this->errors['aarambha_case_management_description'] = __( 'Description is required.', 'aarambha-case-management' ); } return empty( $this->errors ); } /** * Get a previously submitted value. * * @param string $field Field name. * @return string */ private function get_value( string $field ): string { return $this->values[ $field ] ?? ''; } /** * Get a validation error for a field. * * @param string $field Field name. * @return string */ private function get_error( string $field ): string { return $this->errors[ $field ] ?? ''; } /** * Display success message. * * @return void */ private function display_success(): void { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display of a post-redirect success flag, not a state-changing action. if ( ! isset( $_GET['aarambha_case_management_success'] ) ) { return; } // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Read-only display value, sanitized below before output. $case_number = sanitize_text_field( wp_unslash( $_GET['case'] ?? '' ) ); // phpcs:enable ?>