Generate Applicant List

>

generate_results(); ?>

Applicants Found Matching Your Criteria

get_currency($result['profile']['currency']); if ( $selected_currency !== false ) { $currency = $selected_currency['currency_symbol']; } } ?>
", $contact_details) : '-'; ?> Max Price: ' . $currency . esc_html(ph_display_price_field($result['profile']['max_price'])); if ( $percentage_lower != '' && $percentage_higher != '' ) { $match_price_range_lower = ''; if ( !isset($result['profile']['match_price_range_lower_actual']) || ( isset($result['profile']['match_price_range_lower_actual']) && $result['profile']['match_price_range_lower_actual'] == '' ) ) { if ( isset($result['profile']['max_price']) && $result['profile']['max_price'] != '' ) { $match_price_range_lower = (float) $result['profile']['max_price'] - ( (float) $result['profile']['max_price'] * ( (float) $percentage_lower / 100 ) ); } } else { $match_price_range_lower = $result['profile']['match_price_range_lower']; } $match_price_range_higher = ''; if ( !isset($result['profile']['match_price_range_higher_actual']) || ( isset($result['profile']['match_price_range_higher_actual']) && $result['profile']['match_price_range_higher_actual'] == '' ) ) { if ( isset($result['profile']['max_price']) && $result['profile']['max_price'] != '' ) { $match_price_range_higher = (float) $result['profile']['max_price'] + ( (float) $result['profile']['max_price'] * ( (float) $percentage_higher / 100 ) ); } } else { $match_price_range_higher = $result['profile']['match_price_range_higher']; } if ( $match_price_range_lower != '' && $match_price_range_higher != '' ) { $output[] = 'Max Price Range: ' . $currency . esc_html(ph_display_price_field($match_price_range_lower)) . ' to ' . $currency . esc_html(ph_display_price_field($match_price_range_higher)); } } } if ( isset($result['profile']['min_beds']) && $result['profile']['min_beds'] != '' && $result['profile']['min_beds'] != 0 ) { $output[] = 'Min Beds: ' . esc_html(number_format( (float) $result['profile']['min_beds'] )); } if ( isset($result['profile']['property_types']) && is_array($result['profile']['property_types']) && !empty($result['profile']['property_types']) ) { $output_types = array(); foreach ( $result['profile']['property_types'] as $profile_type ) { if ( is_scalar( $profile_type ) && isset( $property_types[$profile_type] ) ) { $output_types[] = $property_types[$profile_type]; } } $output[] = 'Property Types: ' . esc_html(implode(", ", $output_types)); } if ( isset($result['profile']['locations']) && is_array($result['profile']['locations']) && !empty($result['profile']['locations']) ) { $output_locations = array(); foreach ( $result['profile']['locations'] as $profile_location ) { if ( is_scalar( $profile_location ) && isset( $locations[$profile_location] ) ) { $output_locations[] = $locations[$profile_location]; } } $output[] = 'Locations: ' . esc_html(implode(", ", $output_locations)); } if ( isset($result['profile']['notes']) && $result['profile']['notes'] != '' ) { $output[] = 'Additional Requirements: ' . nl2br(esc_html($result['profile']['notes'])); } // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Requirement text is escaped when assembled above; strong/br markup is fixed and currency-symbol filter HTML remains trusted. echo( !empty($output) ? implode("
", $output) : '-' ); break; } case "residential-lettings": { $output = array(); if ( isset($result['profile']['max_rent']) && $result['profile']['max_rent'] != '' && $result['profile']['max_rent'] != 0 ) { $output[] = 'Max Rent: ' . $currency . esc_html(ph_display_price_field($result['profile']['max_rent']) . $result['profile']['rent_frequency']); } if ( isset($result['profile']['min_beds']) && $result['profile']['min_beds'] != '' && $result['profile']['min_beds'] != 0 ) { $output[] = 'Min Beds: ' . esc_html(number_format( (float) $result['profile']['min_beds'] )); } if ( isset($result['profile']['property_types']) && is_array($result['profile']['property_types']) && !empty($result['profile']['property_types']) ) { $output_types = array(); foreach ( $result['profile']['property_types'] as $profile_type ) { if ( is_scalar( $profile_type ) && isset( $property_types[$profile_type] ) ) { $output_types[] = $property_types[$profile_type]; } } $output[] = 'Property Types: ' . esc_html(implode(", ", $output_types)); } if ( isset($result['profile']['locations']) && is_array($result['profile']['locations']) && !empty($result['profile']['locations']) ) { $output_locations = array(); foreach ( $result['profile']['locations'] as $profile_location ) { if ( is_scalar( $profile_location ) && isset( $locations[$profile_location] ) ) { $output_locations[] = $locations[$profile_location]; } } $output[] = 'Locations: ' . esc_html(implode(", ", $output_locations)); } if ( isset($result['profile']['notes']) && $result['profile']['notes'] != '' ) { $output[] = 'Additional Requirements: ' . nl2br(esc_html($result['profile']['notes'])); } // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Requirement text is escaped when assembled above; strong/br markup is fixed and currency-symbol filter HTML remains trusted. echo( !empty($output) ? implode("
", $output) : '-' ); break; } case "commercial": { $output = array(); if ( isset($result['profile']['locations']) && is_array($result['profile']['locations']) && !empty($result['profile']['locations']) ) { $output_locations = array(); foreach ( $result['profile']['locations'] as $profile_location ) { if ( is_scalar( $profile_location ) && isset( $locations[$profile_location] ) ) { $output_locations[] = $locations[$profile_location]; } } $output[] = 'Locations: ' . esc_html(implode(", ", $output_locations)); } if ( isset($result['profile']['notes']) && $result['profile']['notes'] != '' ) { $output[] = 'Additional Requirements: ' . nl2br(esc_html($result['profile']['notes'])); } // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Requirement text is escaped when assembled above; strong/br markup is fixed and currency-symbol filter HTML remains trusted. echo( !empty($output) ? implode("
", $output) : '-' ); break; } } } ?>
false, 'parent' => $property_type ); $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); if ( !empty( $terms ) && !is_wp_error( $terms ) ) { foreach ($terms as $term) { $search_property_types[] = $term->term_id; $args = array( 'hide_empty' => false, 'parent' => $term->term_id ); $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); if ( !empty( $subterms ) && !is_wp_error( $subterms ) ) { foreach ($subterms as $term) { $search_property_types[] = $term->term_id; } } } } } } $search_property_types = array_unique($search_property_types); } $search_locations = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $has_locations && ! empty( $locations_input ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. foreach ( $locations_input as $location ) { $search_locations[] = (int)$location; $args = array( 'hide_empty' => false, 'parent' => $location ); $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); if ( !empty( $terms ) && !is_wp_error( $terms ) ) { foreach ($terms as $term) { $search_locations[] = $term->term_id; $args = array( 'hide_empty' => false, 'parent' => $term->term_id ); $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); if ( !empty( $subterms ) && !is_wp_error( $subterms ) ) { foreach ($subterms as $term) { $search_locations[] = $term->term_id; } } } } } } $search_locations = array_unique($search_locations); $args = array( 'post_type' => 'contact', 'fields' => 'ids', 'nopaging' => true, ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Existing applicant membership is stored in serialized _contact_types metadata; preserve complete list/export results and their extension match checks. Query fetches IDs only. $args['meta_query'] = array(); $args['meta_query'][] = array( 'key' => '_contact_types', 'value' => 'applicant', 'compare' => 'LIKE' ); $applicant_query = new WP_Query($args); $results = array(); if ( $applicant_query->have_posts() ) { $percentage_lower = get_option( 'propertyhive_applicant_match_price_range_percentage_lower', '' ); $percentage_higher = get_option( 'propertyhive_applicant_match_price_range_percentage_higher', '' ); while ( $applicant_query->have_posts() ) { $applicant_query->the_post(); $num_applicant_profiles = get_post_meta( get_the_ID(), '_applicant_profiles', TRUE ); if ( $num_applicant_profiles == '' ) { $num_applicant_profiles = 0; } for ( $i = 0; $i < $num_applicant_profiles; ++$i ) { $profile = get_post_meta( get_the_ID(), '_applicant_profile_' . $i, TRUE ); $match = true; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( !$has_include_non_send_matching_properties ) { if ( !isset($profile['send_matching_properties']) || ( isset($profile['send_matching_properties']) && $profile['send_matching_properties'] != 'yes' ) ) { $match = false; } } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $has_department ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( isset($profile['department']) && $profile['department'] != ph_clean($department_input) ) { $match = false; } } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $has_department && ( $department_input == 'residential-sales' || ph_get_custom_department_based_on($department_input) == 'residential-sales' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $maximum_price_input !== '' && ph_clean($maximum_price_input) != '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. $price = preg_replace("/[^0-9.]/", '', ph_clean($maximum_price_input)); if ( $percentage_lower != '' && $percentage_higher != '' ) { $match_price_range_lower = ''; if ( !isset($profile['match_price_range_lower_actual']) || ( isset($profile['match_price_range_lower_actual']) && $profile['match_price_range_lower_actual'] == '' ) ) { if ( isset($profile['max_price_actual']) && $profile['max_price_actual'] != '' ) { if ( $percentage_lower != '' ) { $match_price_range_lower = $profile['max_price_actual'] - ( $profile['max_price_actual'] * ( $percentage_lower / 100 ) ); } } } else { $match_price_range_lower = $profile['match_price_range_lower_actual']; } $match_price_range_higher = ''; if ( !isset($profile['match_price_range_higher_actual']) || ( isset($profile['match_price_range_higher_actual']) && $profile['match_price_range_higher_actual'] == '' ) ) { if ( isset($profile['max_price_actual']) && $profile['max_price_actual'] != '' ) { if ( $percentage_higher != '' ) { $match_price_range_higher = $profile['max_price_actual'] + ( $profile['max_price_actual'] * ( $percentage_higher / 100 ) ); } } } else { $match_price_range_higher = $profile['match_price_range_higher_actual']; } if ( !($match_price_range_lower == '' && $match_price_range_higher == '') && // Both bounds are not empty !( $price >= $match_price_range_lower && $price <= $match_price_range_higher ) // Price is not within the bounds ) { $match = false; // Assuming you want to set match to false; adjust as needed } } else { if ( isset($profile['max_price_actual']) && $profile['max_price_actual'] !== '' && // Checks if max_price_actual is not an empty string $price > $profile['max_price_actual'] // Checks if price is greater than max_price_actual ) { $match = false; } } } } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $has_department && ( $department_input == 'residential-lettings' || ph_get_custom_department_based_on($department_input) == 'residential-lettings' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $maximum_rent_input !== '' && ph_clean($maximum_rent_input) != '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. $price = preg_replace("/[^0-9.]/", '', ph_clean($maximum_rent_input)); if ( isset($profile['max_price_actual']) && $profile['max_price_actual'] != '' && $profile['max_price_actual'] != 0 && $profile['max_price_actual'] < $price ) { $match = false; } } } if ( // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. $has_department && ( // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. $department_input == 'residential-sales' || // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. $department_input == 'residential-lettings' || // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. ph_get_custom_department_based_on($department_input) == 'residential-sales' || // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. ph_get_custom_department_based_on($department_input) == 'residential-lettings' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $minimum_bedrooms_input !== '' && ph_clean($minimum_bedrooms_input) != '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. $beds = preg_replace("/[^0-9.]/", '', ph_clean($minimum_bedrooms_input)); if ( isset($profile['min_beds']) && $profile['min_beds'] != '' && $profile['min_beds'] != 0 && $profile['min_beds'] > $beds ) { $match = false; } } // Property Types // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $has_property_types && ! empty( $property_types_input ) ) { $found_type = false; foreach ( $search_property_types as $search_property_type ) { if ( isset($profile['property_types']) && is_array($profile['property_types']) && in_array($search_property_type, $profile['property_types']) ) { $found_type = true; } } if ( !$found_type ) { $match = false; } } } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only applicant filters and form display; CSV export separately verifies its nonce and CRM capability. if ( $has_locations && ! empty( $locations_input ) ) { $found_type = false; foreach ( $search_locations as $search_location ) { if ( isset($profile['locations']) && is_array($profile['locations']) && in_array($search_location, $profile['locations']) ) { $found_type = true; } } if ( !$found_type ) { $match = false; } } $match = apply_filters( 'propertyhive_applicant_list_check', $match, get_the_ID(), $profile ); if ( $match ) { $contact = new PH_Contact( get_the_ID() ); $results[] = array( 'contact_id' => get_the_ID(), 'applicant_profile_id' => $i, 'name' => get_the_title(), 'edit_link' => get_edit_post_link(get_the_ID()), 'telephone_number' => $contact->_telephone_number, 'email_address' => $contact->_email_address, 'address' => $contact->get_formatted_full_address(), 'profile' => $profile ); } } } } wp_reset_postdata(); return $results; } private function array_2_csv($results) { // export() verifies the nonce and capability before calling this formatter. // phpcs:ignore WordPress.Security.NonceVerification.Missing -- This private formatter only reads the already-authorized export filters. $request_post = wp_unslash( $_POST ); $has_department = isset( $request_post['department'] ) && is_scalar( $request_post['department'] ); $department_input = $has_department ? sanitize_text_field( $request_post['department'] ) : ''; $locations = array(); $args = array( 'hide_empty' => false, 'parent' => 0 ); $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); if ( !empty( $terms ) && !is_wp_error( $terms ) ) { foreach ($terms as $term) { $locations[$term->term_id] = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); $args = array( 'hide_empty' => false, 'parent' => $term->term_id ); $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); if ( !empty( $subterms ) && !is_wp_error( $subterms ) ) { foreach ($subterms as $term) { $locations[$term->term_id] = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); $args = array( 'hide_empty' => false, 'parent' => $term->term_id ); $subsubterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); if ( !empty( $subsubterms ) && !is_wp_error( $subsubterms ) ) { foreach ($subsubterms as $term) { $locations[$term->term_id] = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); } } } } } } $property_types = array(); $args = array( 'hide_empty' => false, 'parent' => 0 ); $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); if ( !empty( $terms ) && !is_wp_error( $terms ) ) { foreach ($terms as $term) { $property_types[$term->term_id] = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); $args = array( 'hide_empty' => false, 'parent' => $term->term_id ); $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); if ( !empty( $subterms ) && !is_wp_error( $subterms ) ) { foreach ($subterms as $term) { $property_types[$term->term_id] = html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ); } } } } $percentage_lower = get_option( 'propertyhive_applicant_match_price_range_percentage_lower', '' ); $percentage_higher = get_option( 'propertyhive_applicant_match_price_range_percentage_higher', '' ); ob_start(); $df = fopen("php://output", 'w'); $columns = array( 'name' => __( 'Name', 'propertyhive' ), 'email_address' => __( 'Email Address', 'propertyhive' ), 'telephone_number' => __( 'Telephone Number', 'propertyhive' ), 'address' => __( 'Address', 'propertyhive' ), 'department' => __( 'Department', 'propertyhive' ), ); if ( $has_department ) { $department = ph_clean( $department_input ); if ( ph_get_custom_department_based_on($department) !== FALSE ) { $department = ph_get_custom_department_based_on($department); } } if ( isset($department) ) { switch ( $department ) { case "residential-sales": { $columns['maximum_price'] = __( 'Maximum Price', 'propertyhive' ); if ( $percentage_lower != '' && $percentage_higher != '' ) { $columns['maximum_price_range'] = __( 'Maximum Price Range', 'propertyhive' ); } break; } case "residential-lettings": { $columns['maximum_rent'] = __( 'Maximum Rent (PCM)', 'propertyhive' ); break; } } if ( $department == 'residential-sales' || $department == 'residential-lettings' ) { $columns['currency'] = __( 'Currency', 'propertyhive' ); $columns['minimum_bedrooms'] = __( 'Minimum Bedrooms', 'propertyhive' ); $columns['property_types'] = __( 'Property Types', 'propertyhive' ); } } $columns['locations'] = __( 'Locations', 'propertyhive' ); $columns['additional_requirements'] = __( 'Additional Requirements', 'propertyhive' ); // Keep the historical raw POST value as the filter contract for extensions. // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Export nonce and capability are verified by export() before this private formatter is called; the raw value is retained for extension compatibility. $columns = apply_filters( 'propertyhive_export_applicant_list_columns', $columns, $_POST ); fputcsv( $df, $columns, ',', '"', '' ); foreach ($results as $result) { $columns = array( 'name' => $result['name'], 'email_address' => $result['email_address'], 'telephone_number' => $result['telephone_number'], 'address' => $result['address'], 'department' => ( isset($result['profile']['department']) ? propertyhive_get_department_label( $result['profile']['department'] ) : '-' ), ); if ( isset($department) ) { switch ( $department ) { case "residential-sales": { $columns['maximum_price'] = ( isset($result['profile']['max_price']) ? $result['profile']['max_price'] : '' ); if ( $percentage_lower != '' && $percentage_higher != '' ) { $columns['maximum_price_range'] = ''; } if ( !empty($columns['maximum_price']) ) { if ( $percentage_lower != '' && $percentage_higher != '' ) { $match_price_range_lower = ''; if ( !isset($result['profile']['match_price_range_lower_actual']) || ( isset($result['profile']['match_price_range_lower_actual']) && $result['profile']['match_price_range_lower_actual'] == '' ) ) { if ( isset($result['profile']['max_price']) && $result['profile']['max_price'] != '' ) { $match_price_range_lower = (float) $result['profile']['max_price'] - ( (float) $result['profile']['max_price'] * ( (float) $percentage_lower / 100 ) ); } } else { $match_price_range_lower = $result['profile']['match_price_range_lower']; } $match_price_range_higher = ''; if ( !isset($result['profile']['match_price_range_higher_actual']) || ( isset($result['profile']['match_price_range_higher_actual']) && $result['profile']['match_price_range_higher_actual'] == '' ) ) { if ( isset($result['profile']['max_price']) && $result['profile']['max_price'] != '' ) { $match_price_range_higher = (float) $result['profile']['max_price'] + ( (float) $result['profile']['max_price'] * ( (float) $percentage_higher / 100 ) ); } } else { $match_price_range_higher = $result['profile']['match_price_range_higher']; } if ( $match_price_range_lower != '' && $match_price_range_higher != '' ) { $columns['maximum_price_range'] = $match_price_range_lower . ' - ' . $match_price_range_higher; } } } $columns['currency'] = ( isset($result['profile']['currency']) ? $result['profile']['currency'] : 'GBP' ); break; } case "residential-lettings": { $columns['maximum_rent'] = ( isset($result['profile']['max_rent']) ? $result['profile']['max_rent'] : '' ); $columns['currency'] = ( isset($result['profile']['currency']) ? $result['profile']['currency'] : 'GBP' ); break; } } if ( $department == 'residential-sales' || $department == 'residential-lettings' ) { $columns['minimum_bedrooms'] = ( isset($result['profile']['min_beds']) ? $result['profile']['min_beds'] : '' ); $output_types = array(); if ( isset($result['profile']['property_types']) && is_array($result['profile']['property_types']) && !empty($result['profile']['property_types']) ) { foreach ( $result['profile']['property_types'] as $profile_type ) { if ( is_scalar( $profile_type ) && isset( $property_types[$profile_type] ) ) { $output_types[] = $property_types[$profile_type]; } } } $columns['property_types'] = implode(", ", $output_types); } } $output_locations = array(); if ( isset($result['profile']['locations']) && is_array($result['profile']['locations']) && !empty($result['profile']['locations']) ) { foreach ( $result['profile']['locations'] as $profile_location ) { if ( is_scalar( $profile_location ) && isset( $locations[$profile_location] ) ) { $output_locations[] = $locations[$profile_location]; } } } $columns['locations'] = implode(", ", $output_locations); $columns['additional_requirements'] = isset($result['profile']['notes']) ? $result['profile']['notes'] : ''; // Keep the historical raw POST value as the filter contract for extensions. // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Export nonce and capability are verified by export() before this private formatter is called; the raw value is retained for extension compatibility. $columns = apply_filters( 'propertyhive_export_applicant_list_row_data', $columns, $_POST, $result['contact_id'], $result['applicant_profile_id'] ); fputcsv( $df, $columns, ',', '"', '' ); } fclose($df); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Closes the php://output CSV stream. return ob_get_clean(); } public function export() { if ( !isset( $_POST['ph_applicant_export_nonce'] ) || ! check_admin_referer( 'ph_applicant_export', 'ph_applicant_export_nonce', false ) ) { wp_die( esc_html__( 'Invalid request (nonce failure)', 'propertyhive' ), 403 ); } if ( !current_user_can( 'manage_propertyhive' ) ) { wp_die( esc_html__( 'Insufficient permissions', 'propertyhive' ), 403 ); } $filename = 'applicant-list-' . gmdate("YmdHis") . '.csv'; // disable caching $now = gmdate("D, d M Y H:i:s"); header("Expires: Tue, 03 Jul 2001 06:00:00 GMT"); header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate"); header("Last-Modified: {$now} GMT"); // force download header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download"); // disposition / encoding on response body header("Content-Disposition: attachment;filename={$filename}"); header("Content-Transfer-Encoding: binary"); $results = $this->generate_results(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Attachment response is CSV encoded by fputcsv, not HTML; HTML escaping would corrupt exported values. echo $this->array_2_csv($results); die(); } } endif;