Skip to content

Commit 442b533

Browse files
authored
Merge pull request #170 from viest/dev
Feat: nextCellCallback with data type
2 parents 9199a33 + 3605707 commit 442b533

File tree

7 files changed

+175
-53
lines changed

7 files changed

+175
-53
lines changed

ide-helper/helper.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,20 @@ public function openSheet(string $sheetName = NULL, int $skipFlag = 0x00): self
343343
return $this;
344344
}
345345

346+
/**
347+
* Set row cell data type
348+
*
349+
* @param array $types
350+
*
351+
* @return Excel
352+
*
353+
* @author viest
354+
*/
355+
public function setType(array $types): self
356+
{
357+
return $this;
358+
}
359+
346360
/**
347361
* Read values from the sheet
348362
*

include/read.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#define READ_ROW 0x01
1818

1919
int sheet_read_row(xlsxioreadersheet sheet_t);
20-
int is_number(char *value);
20+
int is_number(const char *value);
21+
void data_to_custom_type(const char *string_value, zend_ulong type, zval *zv_result_t);
2122
xlsxioreader file_open(const char *directory, const char *file_name);
2223
void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_type_t, zval *zv_result_t);
2324
xlsxioreadersheet sheet_open(xlsxioreader file_t, const zend_string *zs_sheet_name_t, const zend_long zl_flag);

include/xlswriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef struct {
4444
} xls_resource_read_t;
4545

4646
typedef struct {
47+
zval *zv_type_t;
4748
zend_fcall_info *fci;
4849
zend_fcall_info_cache *fci_cache;
4950
} xls_read_callback_data;

kernel/excel.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,8 @@ PHP_METHOD(vtiful_xls, nextCellCallback)
843843

844844
xls_read_callback_data callback_data;
845845

846+
callback_data.zv_type_t = zend_read_property(vtiful_xls_ce, getThis(), ZEND_STRL(V_XLS_TYPE), 0, NULL);
847+
846848
callback_data.fci = &fci;
847849
callback_data.fci_cache = &fci_cache;
848850

kernel/read.c

Lines changed: 89 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ xlsxioreadersheet sheet_open(xlsxioreader file_t, const zend_string *zs_sheet_na
4242
/* }}} */
4343

4444
/* {{{ */
45-
int is_number(char *value)
45+
int is_number(const char *value)
4646
{
4747
if (strspn(value, ".0123456789") == strlen(value)) {
4848
return XLSWRITER_TRUE;
@@ -52,6 +52,71 @@ int is_number(char *value)
5252
}
5353
/* }}} */
5454

55+
/* {{{ */
56+
void data_to_custom_type(const char *string_value, zend_ulong type, zval *zv_result_t)
57+
{
58+
if (type & READ_TYPE_DATETIME) {
59+
if (!is_number(string_value)) {
60+
goto STRING;
61+
}
62+
63+
double value = strtod(string_value, NULL);
64+
65+
if (value != 0) {
66+
value = (value - 25569) * 86400;
67+
}
68+
69+
if (Z_TYPE_P(zv_result_t) == IS_ARRAY) {
70+
add_next_index_long(zv_result_t, (zend_long)(value + 0.5));
71+
} else {
72+
ZVAL_LONG(zv_result_t, (zend_long)(value + 0.5));
73+
}
74+
75+
return;
76+
}
77+
78+
if (type & READ_TYPE_DOUBLE) {
79+
if (!is_number(string_value)) {
80+
goto STRING;
81+
}
82+
83+
if (Z_TYPE_P(zv_result_t) == IS_ARRAY) {
84+
add_next_index_double(zv_result_t, strtod(string_value, NULL));
85+
} else {
86+
ZVAL_DOUBLE(zv_result_t, strtod(string_value, NULL));
87+
}
88+
89+
return;
90+
}
91+
92+
if (type & READ_TYPE_INT) {
93+
if (!is_number(string_value)) {
94+
goto STRING;
95+
}
96+
97+
zend_long _long_value;
98+
99+
sscanf(string_value, "%" PRIi64, &_long_value);
100+
101+
if (Z_TYPE_P(zv_result_t) == IS_ARRAY) {
102+
add_next_index_long(zv_result_t, _long_value);
103+
} else {
104+
ZVAL_LONG(zv_result_t, _long_value);
105+
}
106+
107+
return;
108+
}
109+
110+
STRING:
111+
112+
if (Z_TYPE_P(zv_result_t) == IS_ARRAY) {
113+
add_next_index_stringl(zv_result_t, string_value, strlen(string_value));
114+
} else {
115+
ZVAL_STRINGL(zv_result_t, string_value, strlen(string_value));
116+
}
117+
}
118+
/* }}} */
119+
55120
/* {{{ */
56121
int sheet_read_row(xlsxioreadersheet sheet_t)
57122
{
@@ -62,7 +127,7 @@ int sheet_read_row(xlsxioreadersheet sheet_t)
62127
/* {{{ */
63128
unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_result_t, zval *zv_type_arr_t, unsigned int flag)
64129
{
65-
zend_ulong _type = READ_TYPE_EMPTY, _cell_index = 0;
130+
zend_ulong _type, _cell_index = 0;
66131
zend_array *_za_type_t = NULL;
67132
char *_string_value = NULL;
68133
zval *_current_type = NULL;
@@ -93,45 +158,7 @@ unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_res
93158
_cell_index++;
94159
}
95160

96-
if (_type & READ_TYPE_DATETIME) {
97-
if (!is_number(_string_value)) {
98-
goto STRING;
99-
}
100-
101-
double value = strtod(_string_value, NULL);
102-
103-
if (value != 0) {
104-
value = (value - 25569) * 86400;
105-
}
106-
107-
add_next_index_long(zv_result_t, (zend_long)(value + 0.5));
108-
continue;
109-
}
110-
111-
if (_type & READ_TYPE_DOUBLE) {
112-
if (!is_number(_string_value)) {
113-
goto STRING;
114-
}
115-
116-
add_next_index_double(zv_result_t, strtod(_string_value, NULL));
117-
continue;
118-
}
119-
120-
if (_type & READ_TYPE_INT) {
121-
if (!is_number(_string_value)) {
122-
goto STRING;
123-
}
124-
125-
zend_long _long_value;
126-
127-
sscanf(_string_value, "%" PRIi64, &_long_value);
128-
add_next_index_long(zv_result_t, _long_value);
129-
continue;
130-
}
131-
132-
STRING:
133-
134-
add_next_index_stringl(zv_result_t, _string_value, strlen(_string_value));
161+
data_to_custom_type(_string_value, _type, zv_result_t);
135162
}
136163

137164
return XLSWRITER_TRUE;
@@ -153,8 +180,8 @@ int sheet_row_callback (size_t row, size_t max_col, void* callback_data)
153180
_callback_data->fci->params = args;
154181
_callback_data->fci->param_count = 3;
155182

156-
ZVAL_LONG(&args[0], row);
157-
ZVAL_LONG(&args[1], max_col);
183+
ZVAL_LONG(&args[0], (row - 1));
184+
ZVAL_LONG(&args[1], (max_col - 1));
158185
ZVAL_STRING(&args[2], "XLSX_ROW_END");
159186

160187
zend_call_function(_callback_data->fci, _callback_data->fci_cache);
@@ -185,9 +212,25 @@ int sheet_cell_callback (size_t row, size_t col, const char *value, void *callba
185212
_callback_data->fci->params = args;
186213
_callback_data->fci->param_count = 3;
187214

188-
ZVAL_LONG(&args[0], row);
189-
ZVAL_LONG(&args[1], col);
190-
ZVAL_STRING(&args[2], value);
215+
ZVAL_LONG(&args[0], (row - 1));
216+
ZVAL_LONG(&args[1], (col - 1));
217+
218+
if (Z_TYPE_P(_callback_data->zv_type_t) != IS_ARRAY) {
219+
ZVAL_STRING(&args[2], value);
220+
}
221+
222+
if (Z_TYPE_P(_callback_data->zv_type_t) == IS_ARRAY) {
223+
zval *_current_type = NULL;
224+
zend_ulong _type = READ_TYPE_EMPTY;
225+
226+
if ((_current_type = zend_hash_index_find(Z_ARR_P(_callback_data->zv_type_t), (col - 1))) != NULL) {
227+
if (Z_TYPE_P(_current_type) == IS_LONG) {
228+
_type = Z_LVAL_P(_current_type);
229+
}
230+
}
231+
232+
data_to_custom_type(value, _type, &args[2]);
233+
}
191234

192235
zend_call_function(_callback_data->fci, _callback_data->fci_cache);
193236

tests/open_xlsx_next_cell_callback.phpt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ $excel->openFile('tutorial.xlsx')->nextCellCallback(function ($row, $cell, $data
2525
@unlink(__DIR__ . '/tutorial.xlsx');
2626
?>
2727
--EXPECT--
28-
cell:1, row:1, value:Item
29-
cell:2, row:1, value:Cost
30-
cell:2, row:1, value:XLSX_ROW_END
31-
cell:1, row:2, value:Item_1
32-
cell:2, row:2, value:Cost_1
33-
cell:2, row:2, value:XLSX_ROW_END
28+
cell:0, row:0, value:Item
29+
cell:1, row:0, value:Cost
30+
cell:1, row:0, value:XLSX_ROW_END
31+
cell:0, row:1, value:Item_1
32+
cell:1, row:1, value:Cost_1
33+
cell:1, row:1, value:XLSX_ROW_END
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
--TEST--
2+
Check for vtiful presence
3+
--SKIPIF--
4+
<?php
5+
require __DIR__ . '/include/skipif.inc';
6+
skip_disable_reader();
7+
?>
8+
--FILE--
9+
<?php
10+
$config = ['path' => './tests'];
11+
$excel = new \Vtiful\Kernel\Excel($config);
12+
$filePath = $excel->fileName('tutorial.xlsx')
13+
->header(['Item', 'Cost', 'Int', 'Double', 'Date'])
14+
->data([
15+
['Item_1', 'Cost_1', 10, 10.9999995],
16+
])
17+
->insertDate(1, 4, 1568904314)
18+
->output();
19+
20+
$excel->openFile('tutorial.xlsx')
21+
->setType([
22+
\Vtiful\Kernel\Excel::TYPE_STRING,
23+
\Vtiful\Kernel\Excel::TYPE_STRING,
24+
\Vtiful\Kernel\Excel::TYPE_INT,
25+
\Vtiful\Kernel\Excel::TYPE_DOUBLE,
26+
\Vtiful\Kernel\Excel::TYPE_TIMESTAMP,
27+
])
28+
->nextCellCallback(function ($row, $cell, $data) {
29+
echo 'cell:' . $cell . ', row:' . $row . PHP_EOL;
30+
var_dump($data);
31+
});
32+
?>
33+
--CLEAN--
34+
<?php
35+
@unlink(__DIR__ . '/tutorial.xlsx');
36+
?>
37+
--EXPECT--
38+
cell:0, row:0
39+
string(4) "Item"
40+
cell:1, row:0
41+
string(4) "Cost"
42+
cell:2, row:0
43+
string(3) "Int"
44+
cell:3, row:0
45+
string(6) "Double"
46+
cell:4, row:0
47+
string(4) "Date"
48+
cell:4, row:0
49+
string(12) "XLSX_ROW_END"
50+
cell:0, row:1
51+
string(6) "Item_1"
52+
cell:1, row:1
53+
string(6) "Cost_1"
54+
cell:2, row:1
55+
int(10)
56+
cell:3, row:1
57+
float(10.9999995)
58+
cell:4, row:1
59+
int(1568904314)
60+
cell:4, row:1
61+
string(12) "XLSX_ROW_END"

0 commit comments

Comments
 (0)