Explorar el Código

Feat: putcsv custom delimiter

viest hace 5 años
padre
commit
712b4fcc0f

+ 7 - 1
include/csv.h

@@ -13,6 +13,12 @@
 #ifndef PHP_EXT_XLS_WRITER_CSV_H
 #define PHP_EXT_XLS_WRITER_CSV_H
 
-unsigned int xlsx_to_csv(zval *stream_resource, xlsxioreadersheet sheet_t, zval *zv_type_arr_t, unsigned int flag, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache);
+unsigned int xlsx_to_csv(
+        zval *stream_resource,
+        const char *delimiter_str, int delimiter_str_len,
+        const char *enclosure_str, int enclosure_str_len,
+        const char *escape_str, int escape_str_len,
+        xlsxioreadersheet sheet_t, zval *zv_type_arr_t, unsigned int flag, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache
+);
 
 #endif // PHP_EXT_XLS_WRITER_CSV_H

+ 46 - 7
kernel/csv.c

@@ -15,15 +15,18 @@
 #include "ext/standard/file.h"
 
 /* {{{ */
-unsigned int xlsx_to_csv(zval *stream_resource, xlsxioreadersheet sheet_t, zval *zv_type_arr_t, unsigned int flag, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
+unsigned int xlsx_to_csv(
+        zval *stream_resource,
+        const char *delimiter_str, int delimiter_str_len,
+        const char *enclosure_str, int enclosure_str_len,
+        const char *escape_str, int escape_str_len,
+        xlsxioreadersheet sheet_t, zval *zv_type_arr_t, unsigned int flag, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache
+)
 {
-    zval *_zv_type_arr_t = NULL;
-    php_stream *_stream_t;
-
     ssize_t ret = 0;
-    char delimiter = ',';
-    char enclosure = '"';
-    int escape_char = (unsigned char) '\\';
+    zval *_zv_type_arr_t = NULL;
+    php_stream *_stream_t = NULL;
+    char delimiter = ',', enclosure = '"', escape_char = '\\';
 
     ZEND_ASSERT(Z_TYPE_P(stream_resource) == IS_RESOURCE);
 
@@ -32,6 +35,42 @@ unsigned int xlsx_to_csv(zval *stream_resource, xlsxioreadersheet sheet_t, zval
         return XLSWRITER_FALSE;
 	}
 
+    if (delimiter_str != NULL) {
+        if (delimiter_str_len < 1) {
+            zend_throw_exception(vtiful_exception_ce, "delimiter must be a character", 190);
+            return XLSWRITER_FALSE;
+        } else if (delimiter_str_len > 1) {
+            zend_throw_exception(vtiful_exception_ce, "delimiter must be a single character", 191);
+            return XLSWRITER_FALSE;
+        }
+
+        delimiter = *delimiter_str;
+    }
+
+    if (enclosure_str != NULL) {
+        if (enclosure_str_len < 1) {
+            zend_throw_exception(vtiful_exception_ce, "enclosure must be a character", 192);
+            return XLSWRITER_FALSE;
+        } else if (enclosure_str_len > 1) {
+            zend_throw_exception(vtiful_exception_ce, "enclosure must be a single character", 193);
+            return XLSWRITER_FALSE;
+        }
+
+        enclosure = *enclosure_str;
+    }
+
+    if (escape_str != NULL) {
+        if (escape_str_len < 1) {
+            zend_throw_exception(vtiful_exception_ce, "escape must be a character", 194);
+            return XLSWRITER_FALSE;
+        } else if (escape_str_len > 1) {
+            zend_throw_exception(vtiful_exception_ce, "escape must be a single character", 195);
+            return XLSWRITER_FALSE;
+        }
+
+        escape_char = *escape_str;
+    }
+
     if (Z_TYPE_P(zv_type_arr_t) == IS_ARRAY) {
         _zv_type_arr_t = zv_type_arr_t;
     }

+ 30 - 6
kernel/excel.c

@@ -176,11 +176,17 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(xls_put_csv_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, fp)
+                ZEND_ARG_INFO(0, delimiter_str)
+                ZEND_ARG_INFO(0, enclosure_str)
+                ZEND_ARG_INFO(0, escape_str)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(xls_put_csv_callback_arginfo, 0, 0, 2)
                 ZEND_ARG_INFO(0, callback)
                 ZEND_ARG_INFO(0, fp)
+                ZEND_ARG_INFO(0, delimiter_str)
+                ZEND_ARG_INFO(0, enclosure_str)
+                ZEND_ARG_INFO(0, escape_str)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(xls_set_type_arginfo, 0, 0, 1)
@@ -991,10 +997,16 @@ PHP_METHOD(vtiful_xls, setType)
  */
 PHP_METHOD(vtiful_xls, putCSV)
 {
-    zval *fp = NULL, *zv_type = NULL;;
+    zval *fp = NULL, *zv_type = NULL;
+    char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL;
+    size_t delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0;
 
-    ZEND_PARSE_PARAMETERS_START(1, 1)
+    ZEND_PARSE_PARAMETERS_START(1, 4)
             Z_PARAM_RESOURCE(fp)
+            Z_PARAM_OPTIONAL
+            Z_PARAM_STRING(delimiter_str, delimiter_str_len)
+            Z_PARAM_STRING(enclosure_str, enclosure_str_len)
+            Z_PARAM_STRING(escape_str,escape_str_len)
     ZEND_PARSE_PARAMETERS_END();
 
     xls_object *obj = Z_XLS_P(getThis());
@@ -1005,7 +1017,10 @@ PHP_METHOD(vtiful_xls, putCSV)
 
     zv_type = zend_read_property(vtiful_xls_ce, getThis(), ZEND_STRL(V_XLS_TYPE), 0, NULL);
 
-    if (xlsx_to_csv(fp, obj->read_ptr.sheet_t, zv_type, READ_SKIP_ROW, NULL, NULL) == XLSWRITER_TRUE) {
+    if (xlsx_to_csv(
+            fp, delimiter_str, delimiter_str_len, enclosure_str, enclosure_str_len, escape_str, escape_str_len,
+            obj->read_ptr.sheet_t, zv_type, READ_SKIP_ROW, NULL, NULL
+            ) == XLSWRITER_TRUE) {
         RETURN_TRUE;
     }
 
@@ -1018,12 +1033,18 @@ PHP_METHOD(vtiful_xls, putCSV)
 PHP_METHOD(vtiful_xls, putCSVCallback)
 {
     zval *fp = NULL, *zv_type = NULL;
-    zend_fcall_info       fci       = empty_fcall_info;
+    zend_fcall_info fci = empty_fcall_info;
     zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
+    char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL;
+    size_t delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0;
 
-    ZEND_PARSE_PARAMETERS_START(2, 2)
+    ZEND_PARSE_PARAMETERS_START(2, 5)
             Z_PARAM_FUNC(fci, fci_cache)
             Z_PARAM_RESOURCE(fp)
+            Z_PARAM_OPTIONAL
+            Z_PARAM_STRING(delimiter_str, delimiter_str_len)
+            Z_PARAM_STRING(enclosure_str, enclosure_str_len)
+            Z_PARAM_STRING(escape_str,escape_str_len)
     ZEND_PARSE_PARAMETERS_END();
 
     xls_object *obj = Z_XLS_P(getThis());
@@ -1034,7 +1055,10 @@ PHP_METHOD(vtiful_xls, putCSVCallback)
 
     zv_type = zend_read_property(vtiful_xls_ce, getThis(), ZEND_STRL(V_XLS_TYPE), 0, NULL);
 
-    if (xlsx_to_csv(fp, obj->read_ptr.sheet_t, zv_type, READ_SKIP_ROW, &fci, &fci_cache) == XLSWRITER_TRUE) {
+    if (xlsx_to_csv(
+            fp, delimiter_str, delimiter_str_len, enclosure_str, enclosure_str_len, escape_str, escape_str_len,
+            obj->read_ptr.sheet_t, zv_type, READ_SKIP_ROW, &fci, &fci_cache
+            ) == XLSWRITER_TRUE) {
         RETURN_TRUE;
     }
 

+ 3 - 0
package.xml

@@ -181,6 +181,7 @@
    <file md5sum="39f7c511d9019c6815bcf7fd0f7e8224" name="tests/chart_style.phpt" role="test" />
    <file md5sum="bfdf9e054f8efd971a65d00eca465f2f" name="tests/chart_title.phpt" role="test" />
    <file md5sum="9badb50b14bd81536bafcfefcb5677d6" name="tests/column_index_from_string.phpt" role="test" />
+   <file name="tests/const_memory_index_out_range.phpt" role="test" />
    <file name="tests/default_format.phpt" role="test" />
    <file name="tests/fix-207.phpt" role="test" />
    <file md5sum="df2a6af4ced4ea7660a1691d18e75e8c" name="tests/format_align.phpt" role="test" />
@@ -223,6 +224,8 @@
    <file md5sum="5811dd930d7b0f916c662139ff1053d4" name="tests/string_from_column_index.phpt" role="test" />
    <file md5sum="42b26f050d9291509d6f583ef43ebde9" name="tests/xlsx_to_csv.phpt" role="test" />
    <file name="tests/xlsx_to_csv_callback.phpt" role="test" />
+   <file name="tests/xlsx_to_csv_callback_custom_delimiter.phpt" role="test" />
+   <file name="tests/xlsx_to_csv_custom_delimiter.phpt" role="test" />
    <file md5sum="a9af7f4ca385ba41b008b50ac67f8e96" name="tests/zoom.phpt" role="test" />
    <file md5sum="f4a2d1a28ad1bf782502d698de0b1907" name="tests/include/skipif.inc" role="test" />
    <file md5sum="bb4256831dfd81f951bd6f4afbe1719f" name="CREDITS" role="doc" />

+ 59 - 0
tests/xlsx_to_csv_callback_custom_delimiter.phpt

@@ -0,0 +1,59 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php
+require __DIR__ . '/include/skipif.inc';
+skip_disable_reader();
+?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx', 'TestSheet1')
+    ->header(['Item', 'Cost'])
+    ->data([
+        ['Item_1', 'Cost_1', 10, 10.9999995],
+    ])
+    ->output();
+
+$fp = fopen('./tests/file.csv', 'w');
+
+$csvResult = $excel->openFile('tutorial.xlsx')
+    ->openSheet()
+    ->putCSVCallback(function($row){
+        return $row;
+    }, $fp, ';');
+
+var_dump($csvResult);
+
+if (($csvHandler = fopen('./tests/file.csv', 'r')) === FALSE) {
+    die('csv file open failure');
+}
+
+while (($data = fgetcsv($csvHandler, 1000, ';')) !== FALSE) {
+    var_dump($data);
+}
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+@unlink(__DIR__ . '/file.csv');
+?>
+--EXPECT--
+bool(true)
+array(2) {
+  [0]=>
+  string(4) "Item"
+  [1]=>
+  string(4) "Cost"
+}
+array(4) {
+  [0]=>
+  string(6) "Item_1"
+  [1]=>
+  string(6) "Cost_1"
+  [2]=>
+  string(2) "10"
+  [3]=>
+  string(10) "10.9999995"
+}

+ 57 - 0
tests/xlsx_to_csv_custom_delimiter.phpt

@@ -0,0 +1,57 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php
+require __DIR__ . '/include/skipif.inc';
+skip_disable_reader();
+?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx', 'TestSheet1')
+    ->header(['Item', 'Cost'])
+    ->data([
+        ['Item_1', 'Cost_1', 10, 10.9999995],
+    ])
+    ->output();
+
+$fp = fopen('./tests/file.csv', 'w');
+
+$csvResult = $excel->openFile('tutorial.xlsx')
+    ->openSheet()
+    ->putCSV($fp, ';');
+
+var_dump($csvResult);
+
+if (($csvHandler = fopen('./tests/file.csv', 'r')) === FALSE) {
+    die('csv file open failure');
+}
+
+while (($data = fgetcsv($csvHandler, 1000, ';')) !== FALSE) {
+    var_dump($data);
+}
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+@unlink(__DIR__ . '/file.csv');
+?>
+--EXPECT--
+bool(true)
+array(2) {
+  [0]=>
+  string(4) "Item"
+  [1]=>
+  string(4) "Cost"
+}
+array(4) {
+  [0]=>
+  string(6) "Item_1"
+  [1]=>
+  string(6) "Cost_1"
+  [2]=>
+  string(2) "10"
+  [3]=>
+  string(10) "10.9999995"
+}