webform.export.inc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * @file
  4. * Provides several different handlers for exporting webform results.
  5. */
  6. /**
  7. * Implements hook_webform_exporters().
  8. *
  9. * Defines the exporters this module implements.
  10. *
  11. * @return
  12. * An "array of arrays", keyed by content-types. The 'handler' slot
  13. * should point to the PHP class implementing this flag.
  14. */
  15. function webform_webform_exporters() {
  16. return array(
  17. 'delimited' => array(
  18. 'title' => t('Delimited text'),
  19. 'description' => t('A plain text file delimited by commas, tabs, or other characters.'),
  20. 'handler' => 'webform_exporter_delimited',
  21. ),
  22. 'excel' => array(
  23. 'title' => t('Microsoft Excel'),
  24. 'description' => t('A file readable by Microsoft Excel.'),
  25. 'handler' => 'webform_exporter_excel',
  26. ),
  27. );
  28. }
  29. /**
  30. * Return a list of exporters suitable for display in a select list.
  31. */
  32. function webform_export_list() {
  33. $exporters = webform_export_fetch_definition();
  34. $list = array();
  35. foreach ($exporters as $name => $exporter) {
  36. $list[$name] = $exporter['title'];
  37. }
  38. return $list;
  39. }
  40. /**
  41. * Returns a Webform exporter definition.
  42. */
  43. function webform_export_fetch_definition($format = NULL) {
  44. static $cache;
  45. if (!isset($cache)) {
  46. $cache = module_invoke_all('webform_exporters');
  47. }
  48. if (isset($format)) {
  49. if (isset($cache[$format])) {
  50. return $cache[$format];
  51. }
  52. }
  53. else {
  54. return $cache;
  55. }
  56. }
  57. /**
  58. * Instantiates a new Webform handler based on the format.
  59. */
  60. function webform_export_create_handler($format, $options) {
  61. $definition = webform_export_fetch_definition($format);
  62. if (isset($definition) && class_exists($definition['handler'])) {
  63. $handler = new $definition['handler']($options);
  64. }
  65. else {
  66. // TODO: Create a default broken exporter.
  67. $handler = new webform_exporter_broken($options);
  68. }
  69. return $handler;
  70. }
  71. class webform_exporter {
  72. function add_row(&$file_handle, $data) {
  73. }
  74. function set_headers($filename) {
  75. drupal_add_http_header('Content-Type', 'application/force-download');
  76. drupal_add_http_header('Pragma', 'public');
  77. drupal_add_http_header('Cache-Control', 'max-age=0');
  78. }
  79. function bof(&$file_handle) {
  80. }
  81. function eof(&$file_handle) {
  82. }
  83. }
  84. class webform_exporter_delimited extends webform_exporter {
  85. var $delimiter;
  86. function webform_exporter_delimited($options) {
  87. $this->delimiter = isset($options['delimiter']) ? $options['delimiter'] : ',';
  88. // Convert tabs.
  89. if ($this->delimiter == '\t') {
  90. $this->delimiter = "\t";
  91. }
  92. }
  93. function bof(&$file_handle) {
  94. $output = '';
  95. // Include at BOM at the beginning of the file for Little Endian.
  96. // This makes tab-separated imports work correctly in MS Excel.
  97. if (function_exists('mb_convert_encoding') && $this->delimiter == "\t") {
  98. $output = chr(255) . chr(254);
  99. }
  100. @fwrite($file_handle, $output);
  101. }
  102. function add_row(&$file_handle, $data) {
  103. foreach ($data as $key => $value) {
  104. // Escape inner quotes and wrap all contents in new quotes.
  105. $data[$key] = '"' . str_replace('"', '""', $data[$key]) . '"';
  106. // Remove <script> tags, which mysteriously cause Excel not to import.
  107. $data[$key] = preg_replace('!<(/?script.*?)>!', '[$1]', $data[$key]);
  108. }
  109. $row = implode($this->delimiter, $data) . "\n";
  110. if (function_exists('mb_convert_encoding')) {
  111. $row = mb_convert_encoding($row, 'UTF-16LE', 'UTF-8');
  112. }
  113. @fwrite($file_handle, $row);
  114. }
  115. function set_headers($filename) {
  116. parent::set_headers($filename);
  117. // Convert tabs.
  118. if ($this->delimiter == "\t") {
  119. $extension = 'tsv';
  120. $content_type = 'text/tab-separated-values';
  121. }
  122. else {
  123. $extension = 'csv';
  124. $content_type = 'text/csv';
  125. }
  126. drupal_add_http_header('Content-Type', $content_type);
  127. drupal_add_http_header('Content-Disposition', "attachment; filename=$filename.$extension");
  128. }
  129. }
  130. /**
  131. * The Excel exporter currently is just a tab-delimited export.
  132. */
  133. class webform_exporter_excel extends webform_exporter_delimited {
  134. var $delimiter;
  135. function webform_exporter_excel($options) {
  136. $options['delimiter'] = '\t';
  137. parent::webform_exporter_delimited($options);
  138. }
  139. function set_headers($filename) {
  140. drupal_add_http_header('Content-Type', 'application/x-msexcel');
  141. drupal_add_http_header('Content-Disposition', "attachment; filename=$filename.xls");
  142. drupal_add_http_header('Pragma', 'public');
  143. drupal_add_http_header('Cache-Control', 'max-age=0');
  144. }
  145. }