'max-width:30%'); //TODO: add count of welfare people, and number of people fully paid //define sorting information with the header //as per http://www.drup-all.com/blog/table-sort-pagination-drupal-7 $header = array(); $header[] = array('data' => t('Id'), 'field' => 'nid', 'sort' => 'asc'); $header[] = array('data' => t('Name'), 'field' => 'booking_lastname'); $header[] = array('data' => t('Booking Status'), 'field' => 'booking_status'); if (variable_get('booking_enable_studygroups', 0) == 1) { $header[] = array('data' => t('Studygroups')); } if (variable_get('booking_enable_roomallocations', 0) == 1) { $header[] = array('data' => t('Room')); } $header[] = array('data' => t('Travel')); $header[] = array('data' => t('Email'), 'field' => 'booking_email'); $header[] = array('data' => t('Payment To Date'), 'field' => 'booking_amount_paid'); $header[] = array('data' => t('Total Payment Required')); $header[] = array('data' => t('Fully paid?')); $header[] = array('data' => t('Refund Processed?'), 'field' => 'booking_refund_processed'); $header[] = array('data' => t('Refund Due'), 'field' => 'booking_refund_due'); $header[] = array('data' => t('Welfare Required?'), 'field' => 'booking_welfare_required'); $header[] = array('data' => t('Committee?'), 'field' => 'booking_committee_member'); $rows = array(); $state_header = array('State', 'Count'); $state_rows = array(); $ecclesia_header = array('State','Ecclesia', 'Count'); $ecclesia_rows = array(); //do some analysis about the people booked in //first the summary of states $query = db_select('booking_person', 'p') ->fields('p', array('booking_state', 'booking_country')) ->condition('p.booking_event_id', $event->eid, '='); $query->groupBy('p.booking_state'); $query->addExpression('COUNT(p.booking_state)', 'state_count'); $query->orderBy('state_count', 'DESC'); $state_stats = $query->execute(); foreach ($state_stats as $state) { if (strcmp($state->booking_country,'Australia') == 0 ) $state_rows[] = array($state->booking_state, $state->state_count); else $non_australia_count += $state->state_count; } //non australian states $state_rows[] = array('International', $non_australia_count); //bookings by ecclesia $query = db_select('booking_person', 'p') ->fields('p', array('booking_ecclesia','booking_state')) ->condition('p.booking_event_id', $event->eid, '='); $query->groupBy('p.booking_ecclesia'); $query->addExpression('COUNT(p.booking_ecclesia)', 'ecclesia_count'); $query->orderBy('booking_state') ->orderBy('ecclesia_count','DESC'); $stats = $query->execute(); foreach ($stats as $ecclesia) { $ecclesia_rows[] = array($ecclesia->booking_state,$ecclesia->booking_ecclesia, $ecclesia->ecclesia_count); } //more detailed summary //allow user-selectable sorting of columns as per http://www.drup-all.com/blog/table-sort-pagination-drupal-7 $query = db_select('booking_person', 'p'); $query->join('booking_price', 'pr', 'pr.pid = p.booking_payment_id'); $query->leftJoin('booking_travel', 't', 'p.nid = t.booking_person_nid'); $query->condition('p.booking_event_id', $event->eid, '=') ->fields('p') ->fields('t') ->fields('pr', array('booking_price', 'booking_late_price')); $table_sort = $query->extend('TableSort')->orderbyHeader($header); $result = $table_sort->execute(); foreach ($result as $person) { $this_row = array(); //$amount_owing = _booking_amount_owing($person->nid, 0, FALSE); $amount_owing = _booking_amount_owing($person, 0, FALSE); //calculate the travel link if ($person->tid > 0) { $travel_link = l(t('Travel'), t('node/!id/edit', array('!id' => $person->tid))); } else { $travel_link = t('N/A'); } //define the row for this person $this_row[] = l(t('View !id', array('!id' => $person->nid)), t('node/!id', array('!id' => $person->nid))); $this_row[] = l(t('!first !last', array('!first' => ucwords($person->booking_firstname), '!last' => ucwords($person->booking_lastname))), t('node/!id/edit', array('!id' => $person->nid)) ); $this_row[] = _booking_status_generate($person->booking_status); if (variable_get('booking_enable_studygroups', 0) == 1) { $this_row[] = l(t('Groups'), t('admin/booking/!id/edit-studygroup-membership', array('!id' => $person->nid))); } if (variable_get('booking_enable_roomallocations', 0) == 1) { $this_row[] =l(t('Room'), t('admin/booking/!id/edit-room', array('!id' => $person->nid))); } $this_row[] = $travel_link; $this_row[] = t('!email', array('!email' => $person->booking_email)); $this_row[] = t('!payment', array('!payment' => $person->booking_amount_paid)); $this_row[] = t('!payment', array('!payment' => $amount_owing == 0 ? $person->booking_total_pay_reqd : _booking_total_due($person))); $this_row[] = t('!fullypaid', array('!fullypaid' => $amount_owing == 0 ? 'Yes' : 'No')); $this_row[] = t('!reqd', array('!reqd' => $person->booking_refund_processed == 'Y' ? 'Yes' : 'No')); $this_row[] = t('!payment', array('!payment' => $person->booking_refund_due)); $this_row[] = t($person->booking_welfare_required == 'Y' ? 'Yes' : 'No'); $this_row[] = t($person->booking_committee_member == 'Y' ? 'Yes' : 'No'); $rows[] = $this_row; //add up the total paid $total_paid += $person->booking_amount_paid; //subtract any refund if ($person->booking_refund_processed == 'Y' && $person->booking_refund_due > 0) { $total_refunds += $person->booking_refund_due; } //travel form completed? if (! _booking_person_studygroups_cleanup($person->tid)) $travelform_count++; //booking status if ($person->booking_status == 0) $notpaid_counter++; elseif ($person->booking_status == 1) $bookedin_counter++; elseif ($person->booking_status == 2) $waiting_counter++; elseif ($person->booking_status == 5) $hosts_counter++; else $notcoming_counter++; //welfare if ($person->booking_welfare_required == 'Y') $welfare_count++; //committee? if ($person->booking_committee_member == 'Y') $committee_count++; //fully paid? if ($amount_owing == 0) $fullypaid_count++; $person_count++; //general stats for booked in people if ($person->booking_status == 1) { $dob_total += $person->booking_dob; if ($person->booking_gender == 'M') { $male_count++; $male_dob_total += $person->booking_dob; } else { $female_count++; $female_dob_total += $person->booking_dob; } if ($person->booking_baptised == 'Y') $baptised_count++; if ($person->booking_married == 'Y') $married_count++; } } //output everything $output .= t("
There are !boys males and !girls females currently booked in. Of these, !baptised are baptised and !married are married.
", array('!boys' => $male_count, '!girls' => $female_count, '!baptised' => $baptised_count, '!married' => $married_count )); $output .= t("The combined average age at the start of the week will be !average.
The male average age will be !maleaverage.
The female average age will be !femaleaverage.
There are !bookedin registrations currently booked in, !waiting on waiting list, !notpaid haven't paid, !hosts are hosts, " . "and !notcoming are no longer coming, which comes to a total of !total people who have filled in the registration form. !travel people have filled in their travel form.
", array('!bookedin' => $bookedin_counter, '!waiting' => $waiting_counter, '!notpaid' => $notpaid_counter, '!total' => $person_count, '!travel' => $travelform_count, '!notcoming' => $notcoming_counter, '!hosts' => $hosts_counter)); $output .= t("There are !welfare people with special financial consideration approved, and !committee people on the committee. " . "!fullypaid people have completed their payments.
", array('!welfare' => $welfare_count, '!fullypaid' => $fullypaid_count, '!committee' => $committee_count, )); $output .= t("Total amount paid: $!paid, minus $!refunds in refunds.", array('!paid' => $total_paid, '!refunds' => $total_refunds)); $output .= t("The following table presents payment entries from paypal and manual payments that have been made for !event.
", array('!event' => $event->booking_eventname)); $output .= theme('table', array('header' => $header, 'rows' => $rows)); $output .= t("Gross amount paid: $!paid. Total amount of fees paid: $!fees
", array('!paid' => $total_paid, '!fees' => $total_fees)); return $output; } /** * List everyone's flight info */ function booking_report_flight_details() { global $event; $form = array(); $prefix = t("View flight information for all attendees with status currently set to booked in.
"); $header = array( 'booking_name' => array('data' => t('Name'), 'field' => 'booking_lastname'), 'booking_destination_country' => array('data' => t('Country'), 'field' => 'booking_destination_country'), 'booking_outflight_bookingnum' => array('data' => t('Reference'), 'field' => 'booking_outflight_bookingnum'), 'booking_outflight_flightnum' => array('data' => t('Flight #'), 'field' => 'booking_outflight_flightnum'), 'booking_outflight_origin' => array('data' => t('Description'), 'field' => 'booking_outflight_origin'), 'booking_outflight_origin_ts' => array('data' => t('Departure Time'), 'field' => 'booking_outflight_origin_ts'), 'booking_outflight_connecting_flightnum' => array('data' => t('Connecting Flight'), 'field' => 'booking_outflight_connecting_flightnum'), 'booking_outflight_destination' => array('data' => t('Description'), 'field' => 'booking_outflight_destination'), 'booking_outflight_destination_ts' => array('data' => t('Time'), 'field' => 'booking_outflight_destination_ts'), 'booking_rtrnflight_bookingnum' => array('data' => t('Return Reference'), 'field' => 'booking_rtrnflight_bookingnum'), 'booking_rtrnflight_flightnum' => array('data' => t('Flight #'), 'field' => 'booking_rtrnflight_flightnum'), 'booking_rtrnflight_origin' => array('data' => t('Description'), 'field' => 'booking_rtrnflight_origin'), 'booking_rtrnflight_origin_ts' => array('data' => t('Time'), 'field' => 'booking_rtrnflight_origin_ts'), ); $query = db_select('booking_person', 'p'); $query->fields('p'); $db_and = db_and(); $db_and->condition('p.booking_event_id', $event->eid, '='); $db_and->condition('p.booking_status', 1, '='); $query->condition($db_and); $table_sort = $query->extend('TableSort')->orderbyHeader($header); $result = $table_sort->execute(); foreach($result as $data) { $name_link = l(t('!first !last', array('!first' => ucwords($data->booking_firstname), '!last' => ucwords($data->booking_lastname))), t('node/!id', array('!id' => $data->nid)) ); $rows[] = array ( 'data' => array( $name_link, $data->booking_destination_country, $data->booking_outflight_bookingnum, $data->booking_outflight_flightnum, $data->booking_outflight_origin, $data->booking_outflight_origin_ts == 0 ? '' : format_date($data->booking_outflight_origin_ts, 'custom', 'd/m/Y H:i'), $data->booking_outflight_connecting_flightnum, $data->booking_outflight_destination, $data->booking_outflight_destination_ts == 0 ? '' : format_date($data->booking_outflight_destination_ts, 'custom', 'd/m/Y H:i'), $data->booking_rtrnflight_bookingnum, $data->booking_rtrnflight_flightnum, $data->booking_rtrnflight_origin, $data->booking_rtrnflight_origin_ts == 0 ? '' : format_date($data->booking_rtrnflight_origin_ts, 'custom', 'd/m/Y H:i'), ), ); } $result = array ( 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'table' => array ( '#theme' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => 'sort-table'), //'#sticky' => FALSE, ) ); return $result; } function booking_coming_page() { global $event; $output = ""; $table = ""; $attributes = array('style' => 'max-width:60%'); $booking_limit = variable_get('booking_regn_limit','350'); $rows = array(); //work out whether to include the team colour in this page if (variable_get('booking_publish_readinggroups', 0) == 1) { $header = array('Name', 'Team Colour', 'State'); } else { $header = array('Name', 'State'); } if (variable_get('booking_auto_show_on_lists', 1) == 1) { $or = db_or()->condition('p.booking_status', 0)->condition('p.booking_status', 1); $result = db_select('booking_person', 'p') ->fields('p', array('booking_firstname', 'booking_lastname', 'booking_state', 'booking_readinggroup', 'booking_country')) ->condition($or) ->condition('p.booking_event_id', $event->eid, '=') ->orderBy('booking_country') ->orderBy('booking_state') ->orderBy('booking_lastname') ->orderBy('booking_firstname') ->execute(); } else { $result = db_select('booking_person', 'p') ->fields('p', array('booking_firstname', 'booking_lastname', 'booking_state', 'booking_readinggroup', 'booking_country')) ->condition('p.booking_status', 1) ->condition('p.booking_event_id', $event->eid, '=') ->orderBy('booking_country') ->orderBy('booking_state') ->orderBy('booking_lastname') ->orderBy('booking_firstname') ->execute(); /* $result = db_query('SELECT booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country FROM ( SELECT booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country FROM {booking_person} WHERE booking_status = 1 and booking_event_id = :eid ) AS booking ORDER BY booking_state, booking_lastname, booking_firstname', array(':eid' => $event->eid)); */ } //while ($booking = db_fetch_object($result)) { //watchdog('booking', "Who's coming query: @info", array('@info' => var_export($result, TRUE))); foreach ($result as $person) { $state = $person->booking_country === variable_get('booking_default_country') ? $person->booking_state : $person->booking_country; //if we're allowed to publish reading groups, specify them in the array element if (variable_get('booking_publish_readinggroups', 0) == 1) { $rows[] = array( t('!first !last', array('!first' => ucwords($person->booking_firstname), '!last' => ucwords($person->booking_lastname))), t('!group',array('!group' => $person->booking_readinggroup)), t('!state', array('!state' => $state)), ); } //don't publish reading group information else { $rows[] = array( t('!first !last', array('!first' => ucwords($person->booking_firstname), '!last' => ucwords($person->booking_lastname))), t('!state', array('!state' => $state)), ); } } //watchdog('booking', "Who's coming formatted: @info", array('@info' => var_export($rows, TRUE))); //output the results //check there were some bookings if (count($rows) > 0) { if (count($rows) >= $booking_limit) { //there is a waiting list $output .= token_replace(variable_get('booking_whoscoming_pre_waitlist_text'), booking_define_tokens()); } else { //there's no waiting list $output .= token_replace(variable_get('booking_whoscoming_pre_text'), booking_define_tokens()); } //theme the table of registrations $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes)); } else { //no bookings $output .= token_replace(variable_get('booking_whoscoming_pre_noregistrations_text'), booking_define_tokens()); } //include any post-text $output .= token_replace(variable_get('booking_whoscoming_post_text'), booking_define_tokens()); return $output; } function booking_waitinglist_page() { global $event; $output = ""; $table = ""; $count = 1; //$header = array('Name', 'Occupation', 'State'); $header = array('Name', 'State', 'Position'); $booking_limit = variable_get('booking_regn_limit','350'); $rows = array(); /* $result = db_query('SELECT DISTINCT nid, booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country FROM ( SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_country, p.booking_readinggroup, pay.booking_payment_date FROM {booking_person} p, {booking_payment} pay WHERE booking_status = 2 and booking_event_id = :eid and p.nid = pay.booking_person_nid ) AS booking ORDER BY booking_payment_date', array(':eid' => $event->eid)); */ $result = db_query('SELECT DISTINCT nid, booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country, booking_status FROM ( SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_country, p.booking_readinggroup, pay.booking_payment_date, p.booking_status FROM {booking_person} p, {booking_payment} pay WHERE booking_event_id = :eid and p.nid = pay.booking_person_nid and ( booking_status = 2 or booking_status = 4) ) AS booking ORDER BY booking_status, booking_payment_date', array(':eid' => $event->eid)); //watchdog('booking', "Who's coming query: @info", array('@info' => var_export($result, TRUE))); foreach ($result as $person) { $rows[] = array( t('!first !last', array('!first' => ucwords($person->booking_firstname), '!last' => ucwords($person->booking_lastname))), //only for when we have readings groups //t('!group',array('!group' => $person->booking_readinggroup)), t('!state', array('!state' => $person->booking_country == 'Australia' ? $person->booking_state : $person->booking_country)), t($count++), ); } //watchdog('booking', "Who's coming formatted: @info", array('@info' => var_export($rows, TRUE))); //output the results //check there were people on the waiting list if (count($rows) > 0) { //include the pre-text $output .= token_replace(variable_get('booking_waitingpage_pre_text'), booking_define_tokens()); //theme the table of waiting list people $output .= theme('table', array('header' => $header, 'rows' => $rows)); } else { //no one on the waiting list $output .= token_replace(variable_get('booking_waitingpage_pre_nowaitlist_text'), booking_define_tokens()); } //include any post-text $output .= token_replace(variable_get('booking_waitingpage_post_text'), booking_define_tokens()); return $output; } function ucname($string) { $string =ucwords(strtolower($string)); foreach (array('-', '\'') as $delimiter) { if (strpos($string, $delimiter)!==false) { $string =implode($delimiter, array_map('ucfirst', explode($delimiter, $string))); } } return $string; } /** * Generate a CSV file as a report of all current registrations */ function booking_csv_report() { global $event; $name = 'bookings-' . format_date(time(), 'custom', 'Y-m-d-His'); $filename = file_directory_temp() . '/' . $name; $delimiter = ','; $enclosure = '"'; $encloseAll = true; $nullToMysqlNull = true; $delimiter_esc = preg_quote($delimiter, '/'); $enclosure_esc = preg_quote($enclosure, '/'); $readinggroup = "session" . variable_get('booking_readinggroup_id','7'); /* $fields_to_skip = array('booking_payment_id', 'booking_event_id', 'booking_skills_childminding', 'booking_passport_issue_date', 'booking_passport_expiry_date', 'booking_passport_num', 'booking_passport_num', 'booking_mission_experience_details', 'booking_passport_issue_location', 'booking_passport_issue_name', 'booking_skills_builder', 'booking_skills_cooking', 'booking_skills_language', 'booking_skills_language_details', 'booking_skills_other', 'booking_skills_other_details'); */ $builtin_fields_to_skip = array('booking_event_id'); $custom_fields_to_skip = explode(";", variable_get('booking_csv_exclude_fields', '')); $fields_to_skip = array_merge($builtin_fields_to_skip, $custom_fields_to_skip); $datetime_fields = array('booking_outflight_origin_ts', 'booking_outflight_destination_ts', 'booking_rtrnflight_origin_ts', 'booking_rtrnflight_destination_ts', 'booking_timestamp', 'booking_flight_datetime_inbound', 'booking_flight_datetime_outbound'); //query the db /* $query = db_select('booking_person', 'p'); $query->join('booking_price', 'pr', 'p.booking_payment_id = pr.pid'); $query->condition('p.booking_event_id', $event->eid) ->fields('p') ->fields('pr', array('booking_price', 'booking_price_descrip')); $result = $query->execute()->fetchAll(); */ /* //pivot table based on http://anothermysqldba.blogspot.de/2013/06/pivot-tables-example-in-mysql.html $query = db_query("select distinct p.*, s1.booking_session_id as session1, s1.booking_is_leader as session1_leader, s1.booking_is_reserveleader as session1_reserveleader, s1.booking_is_helper as session1_helper, s2.booking_session_id as session2, s2.booking_is_leader as session2_leader, s2.booking_is_reserveleader as session2_reserveleader, s2.booking_is_helper as session2_helper, s3.booking_session_id as session3, s3.booking_is_leader as session3_leader, s3.booking_is_reserveleader as session3_reserveleader, s3.booking_is_helper as session3_helper, s4.booking_session_id as session4, s4.booking_is_leader as session4_leader, s4.booking_is_reserveleader as session4_reserveleader, s4.booking_is_helper as session4_helper, s5.booking_session_id as session5, s5.booking_is_leader as session5_leader, s5.booking_is_reserveleader as session5_reserveleader, s5.booking_is_helper as session5_helper, s6.booking_session_id as session6, s6.booking_is_leader as session6_leader, s6.booking_is_reserveleader as session6_reserveleader, s6.booking_is_helper as session6_helper, s7.booking_session_id as readinggroup, s7.booking_is_leader as readinggroup_leader, s7.booking_is_reserveleader as readinggroup_reserveleader, s7.booking_is_helper as readinggroup_helper, pr.booking_price, pr.booking_price_descrip, t.* from {booking_person} p inner join {booking_price} pr on p.booking_payment_id = pr.pid left outer join {booking_travel} t on p.nid = t.booking_person_nid left outer join {booking_studygroup_mapping} s1 on p.nid = s1.booking_node_id and s1.booking_studygroup_id = 1 left outer join {booking_studygroup_mapping} s2 on p.nid = s2.booking_node_id and s2.booking_studygroup_id = 2 left outer join {booking_studygroup_mapping} s3 on p.nid = s3.booking_node_id and s3.booking_studygroup_id = 3 left outer join {booking_studygroup_mapping} s4 on p.nid = s4.booking_node_id and s4.booking_studygroup_id = 4 left outer join {booking_studygroup_mapping} s5 on p.nid = s5.booking_node_id and s5.booking_studygroup_id = 5 left outer join {booking_studygroup_mapping} s6 on p.nid = s6.booking_node_id and s6.booking_studygroup_id = 6 left outer join {booking_studygroup_mapping} s7 on p.nid = s7.booking_node_id and s7.booking_studygroup_id = 7 where p.booking_event_id = :eid ORDER BY p.nid", array('eid' => $event->eid)); $result = $query->fetchAllAssoc('nid'); */ $result = booking_load_query(NULL, TRUE); //watchdog('booking', "CSV raw data: @info", array('@info' => var_export($result, TRUE))); //open the filehandle $handle = @fopen($filename, 'w'); //write the header based on the first result $header_array = array(); foreach (reset($result) as $key => $value) { if (in_array($key, $fields_to_skip)) continue; $header_array[] = $key; //add in a special column for a processed version of the date of birth if (strcmp($key,"booking_dob") == 0) $header_array[] = "booking_dob_processed"; //add in a calculated field for amount owing if (strcmp($key, "nid") == 0) $header_array[] = "booking_amount_owing"; } $header = implode( $delimiter, $header_array ); //watchdog('booking', "CSV header: @info", array('@info' => var_export($header_array, TRUE))); @fwrite($handle, $header . "\n"); //each record foreach ($result as $record) { //watchdog('booking', "CSV raw data entry: @info", array('@info' => var_export($record, TRUE))); $output = array(); //each keypair in the record foreach ($record as $key => $value) { //fields to skip if (in_array($key, $fields_to_skip)) continue; //check for null if ($value === NULL && $nullToMysqlNull) { $output[] = 'NULL'; continue; } //capitalise street name and suburb name if ($key == 'booking_street' || $key == 'booking_suburb') $value = ucname($value); //handle dates if ($key == 'booking_dob') { $output[] = format_date($value, 'custom', 'd/m/Y'); $output[] = '"' . _booking_avg_age($value, 1, $event->booking_event_start) . '"'; continue; } if ($key == 'booking_passport_expiry_date') { $output[] = format_date($value, 'custom', 'd/m/Y'); continue; } //handle more exact dates if (in_array($key, $datetime_fields)) { $output[] = $value == 0 ? '0' : format_date($value, 'custom', 'd/m/Y H:i'); continue; } //booking status if ($key == 'booking_status') { $output[] = _booking_status_generate($value); continue; } //studygroup session roles if (preg_match("/session\d+_role/", $key)) { $output[] = _booking_studygroup_role_lookup($value); continue; } //room location if ($key == 'booking_room_location_id') { $output[] = _booking_room_location_lookup($value); continue; } //room bed type if ($key == 'booking_room_bedtype') { $output[] = _booking_room_bedtype_lookup($value); continue; } //reading group team colour if ($key == $readinggroup) { $output[] = _booking_readinggroup_colour_lookup($value); continue; } //add in the amount owing using the nid as the key if ($key == 'nid') { $output[] = $value; //this is really hacky since it does another database query for each person //$output[] = _booking_amount_owing($value, 0, FALSE); $output[] = _booking_amount_owing($record); continue; } // Enclose fields containing $delimiter, $enclosure or whitespace if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $value ) ) { $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure; } else { $output[] = $field; } } $row = implode($delimiter, $output) . "\n"; @fwrite($handle, $row); //$index++; } @fclose($handle); drupal_add_http_header("Content-type", "application/octet-stream; charset=utf-8"); drupal_add_http_header("Content-Disposition", "attachment; filename=" . $name . ".csv"); @readfile($filename); @unlink($filename); exit(0); }