CsvController.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. require_once(dirname(__FILE__).'/DbController.php');
  3. require_once(dirname(__FILE__).'/IqdParserController.php');
  4. require_once(dirname(__FILE__).'/../models/CsvConfig.php');
  5. class CsvController
  6. {
  7. /** @var DbController */
  8. private $db;
  9. private $conf;
  10. /** @var CsvConfig */
  11. private $csv;
  12. private $data;
  13. private $header;
  14. public function __construct($csvConfig = false)
  15. {
  16. $this->csv = ($csvConfig) ? $csvConfig : new CsvConfig();
  17. $this->conf = array("report" => "", "export_query" => "");
  18. }
  19. public function csvExport()
  20. {
  21. $res = $this->db->Query($this->conf['export_query']);
  22. if ($this->db->Error($this->conf['export_query'])) return false;
  23. $firstRow = $res->fetch(PDO::FETCH_ASSOC);
  24. if (!$firstRow) return false;
  25. $columns = array_keys($firstRow);
  26. $this->columnDetails = array();
  27. for ($i = 0; $i < count($firstRow); $i++) {
  28. $$this->column_details[$columns[$i]] = $this->getColumnTypeFromQuery($res, $i);
  29. }
  30. $header = $this->db->getHeaderNames($this->conf['report'], $columns);
  31. $fwh = fopen($this->conf['filename'], "w");
  32. fwrite($fwh, implode(';', $header)."\n");
  33. fwrite($fwh, implode(';', $this->encodeRow($firstRow))."\n");
  34. while($row = $res->fetch(PDO::FETCH_ASSOC)) {
  35. fwrite($fwh, implode(';', $this->encodeRow($row))."\n");
  36. }
  37. fclose($fwh);
  38. return true;
  39. }
  40. public function getHeader ()
  41. {
  42. if (!$this->header) {
  43. $firstRow = $this->getHeaderFromCsv();
  44. $this->header = ($this->csv->Header) ? $firstRow : $this->getArtificialHeader(count($firstRow));
  45. }
  46. return $this->header;
  47. }
  48. private function getRow ($handle)
  49. {
  50. $row = str_replace("\r\n", "", fgets($handle));
  51. return ($this->csv->Encoding == "ansi") ? mb_convert_encoding($row, "ISO-8859-1", "UTF-8") : $row;
  52. }
  53. public function getHeaderFromCsv ()
  54. {
  55. if (($handle = fopen($this->csv->Filename, "r")) === false) return false;
  56. $header = $this->getRow($handle);
  57. fclose($handle);
  58. return $this->getHeaderFromString($header);
  59. }
  60. public function getHeaderFromString ($rowString)
  61. {
  62. $row = explode($this->csv->Delimiter, $rowString);
  63. return array_map("IqdParserController::stringConvert", $row);
  64. }
  65. public function import ($callback = "CsvController::identity")
  66. {
  67. if (($handle = fopen($this->csv->Filename, "r")) === false) return false;
  68. if ($this->csv->Header) {
  69. $this->header = $this->getHeaderFromString($this->getRow($handle));
  70. }
  71. $result = array();
  72. while ($row = $this->getRow($handle)) {
  73. $result[] = call_user_func($callback, $this->decodeRow(explode($this->csv->Delimiter, $row)));
  74. }
  75. fclose($handle);
  76. return $result;
  77. }
  78. private static function identity ($var)
  79. {
  80. return $var;
  81. }
  82. private static function sqlInsert ($var)
  83. {
  84. return "('" . implode("','", $var) . "')";
  85. }
  86. /**
  87. * @param PDOStatement $query
  88. * @param string $column
  89. * @return string
  90. */
  91. private function getColumnTypeFromQuery($query, $column) {
  92. $meta = $query->getColumnMeta($column);
  93. return $meta['native_type'];
  94. }
  95. public function convertArray ($tableArray)
  96. {
  97. $result = "";
  98. foreach ($tableArray as $row)
  99. {
  100. $result .= $this->encodeRow($row);
  101. }
  102. return $result;
  103. }
  104. public function decodeRow ($row)
  105. {
  106. if (!$this->header) {
  107. $this->header = $this->getArtificialHeader(count($row));
  108. }
  109. $result = array_combine($this->header, array_fill(0, count($this->header), ''));
  110. foreach ($row as $i => $col) {
  111. $result[$this->header[$i]] = $this->decodeColumn($col);
  112. }
  113. return $result;
  114. }
  115. private function decodeColumn ($col)
  116. {
  117. $col = str_replace("\"", "", $col);
  118. $col = str_replace("'", "", $col);
  119. $col = trim($col);
  120. if (preg_match("/^\d+,\d+$/", $col)) {
  121. return str_replace(",", ".", $col);
  122. }
  123. if (preg_match("/^(\d{1,2})\.(\d{1,2})\.(\d{2,4})$/", $col, $m)) {
  124. return "{$m[3]}-{$m[2]}-{$m[1]}";
  125. }
  126. return $col;
  127. }
  128. public function encodeRow ($row) {
  129. if (!$this->header) {
  130. $this->header = implode(";", array_keys($row));
  131. $this->data = array();
  132. }
  133. $result = array();
  134. foreach ($row as $key => $value)
  135. {
  136. $result[] = $this->encodeColumn($value);
  137. }
  138. $csv = implode(';', $result);
  139. $this->data[] = $csv;
  140. return $csv . "\r\n";
  141. }
  142. private function encodeColumn ($col, $format = "VAR_STRING") {
  143. switch ($format) {
  144. case 'VAR_STRING':
  145. return trim($col);
  146. case 'FLOAT':
  147. case 'NEWDECIMAL':
  148. return number_format($col, 2, ",", "");
  149. case 'DATE':
  150. return ($format == '0000-00-00') ? "" : $col;
  151. }
  152. return $col;
  153. }
  154. public function exportToString ()
  155. {
  156. if ($this->csv->Header) {
  157. array_unshift($this->data, $this->header);
  158. }
  159. return implode("\r\n", $this->data);
  160. }
  161. private function getArtificialHeader ($count)
  162. {
  163. $result = array();
  164. for ($i = 1; $i <= $count; $i++) {
  165. $result[] = "col" . $i;
  166. }
  167. return $result;
  168. }
  169. }