diff --git a/config.m4 b/config.m4 index 43ebb18..0fb2694 100644 --- a/config.m4 +++ b/config.m4 @@ -8,7 +8,7 @@ PHP_ARG_WITH(libxlsxio, system libxlsxio, [ --with-libxlsxio=DIR Use system libxlsxio], no, no) PHP_ARG_ENABLE(reader, enable xlsx reader support, -[ --enable-reader Enable xlsx reader?], no, no) +[ --enable-reader Enable xlsx reader?], yes, yes) if test "$PHP_XLSWRITER" != "no"; then xls_writer_sources=" diff --git a/include/exception.h b/include/exception.h index 6be7702..a65e428 100644 --- a/include/exception.h +++ b/include/exception.h @@ -17,4 +17,6 @@ extern zend_class_entry *vtiful_exception_ce; VTIFUL_STARTUP_FUNCTION(exception); +char* exception_message_map(int code); + #endif diff --git a/include/xlswriter.h b/include/xlswriter.h index 07ccc7f..57756a6 100644 --- a/include/xlswriter.h +++ b/include/xlswriter.h @@ -161,12 +161,12 @@ typedef struct _vtiful_validation_object { } \ } while(0); -#define WORKSHEET_WRITER_EXCEPTION(error) \ - do { \ - if(error > LXW_NO_ERROR) { \ - zend_throw_exception(vtiful_exception_ce, "Worksheet write exception", error); \ - return; \ - } \ +#define WORKSHEET_WRITER_EXCEPTION(error) \ + do { \ + if(error > LXW_NO_ERROR) { \ + zend_throw_exception(vtiful_exception_ce, exception_message_map(error), error); \ + return; \ + } \ } while(0) #define FCALL_TWO_ARGS(bucket) \ @@ -207,6 +207,21 @@ typedef struct _vtiful_validation_object { #define PROP_OBJ(zv) Z_OBJ_P(zv) #endif +#if PHP_VERSION_ID < 80000 +#define Z_PARAM_STRING_OR_NULL(dest, dest_len) \ + Z_PARAM_STRING_EX(dest, dest_len, 1, 0) +#define Z_PARAM_STR_OR_NULL(dest) \ + Z_PARAM_STR_EX(dest, 1, 0) +#define Z_PARAM_RESOURCE_OR_NULL(dest) \ + Z_PARAM_RESOURCE_EX(dest, 1, 0) +#define Z_PARAM_DOUBLE_OR_NULL(dest, is_null) \ + Z_PARAM_DOUBLE_EX(dest, is_null, 1, 0) +#define Z_PARAM_LONG_OR_NULL(dest, is_null) \ + Z_PARAM_LONG_EX(dest, is_null, 1, 0) +#define Z_PARAM_ARRAY_OR_NULL(dest) \ + Z_PARAM_ARRAY_EX(dest, 1, 0) +#endif + static inline xls_object *php_vtiful_xls_fetch_object(zend_object *obj) { if (obj == NULL) { return NULL; diff --git a/kernel/csv.c b/kernel/csv.c index 42aa4d0..5f0eb05 100644 --- a/kernel/csv.c +++ b/kernel/csv.c @@ -94,14 +94,22 @@ unsigned int xlsx_to_csv( zend_call_function(fci, fci_cache); if (Z_TYPE(retval) == IS_ARRAY) { +#if PHP_VERSION_ID >= 80100 + ret = php_fputcsv(_stream_t, &retval, delimiter, enclosure, escape_char, NULL); +#else ret = php_fputcsv(_stream_t, &retval, delimiter, enclosure, escape_char); +#endif } zval_ptr_dtor(&retval); goto CLEAN_UP_SCENE; } +#if PHP_VERSION_ID >= 80100 + ret = php_fputcsv(_stream_t, &_zv_tmp_row, delimiter, enclosure, escape_char, NULL); +#else ret = php_fputcsv(_stream_t, &_zv_tmp_row, delimiter, enclosure, escape_char); +#endif CLEAN_UP_SCENE: diff --git a/kernel/excel.c b/kernel/excel.c index ad4588b..2656d9b 100644 --- a/kernel/excel.c +++ b/kernel/excel.c @@ -327,7 +327,7 @@ PHP_METHOD(vtiful_xls, fileName) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(zs_file_name) Z_PARAM_OPTIONAL - Z_PARAM_STR(zs_sheet_name) + Z_PARAM_STR_OR_NULL(zs_sheet_name) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -367,7 +367,7 @@ PHP_METHOD(vtiful_xls, addSheet) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STR(zs_sheet_name) + Z_PARAM_STR_OR_NULL(zs_sheet_name) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -458,7 +458,7 @@ PHP_METHOD(vtiful_xls, constMemory) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(zs_file_name) Z_PARAM_OPTIONAL - Z_PARAM_STR(zs_sheet_name) + Z_PARAM_STR_OR_NULL(zs_sheet_name) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -470,7 +470,11 @@ PHP_METHOD(vtiful_xls, constMemory) if(obj->write_ptr.workbook == NULL) { xls_file_path(zs_file_name, dir_path, &file_path); - lxw_workbook_options options = {.constant_memory = LXW_TRUE, .tmpdir = NULL}; + lxw_workbook_options options = { + .constant_memory = LXW_TRUE, + .tmpdir = NULL, + .use_zip64 = LXW_TRUE + }; if(zs_sheet_name != NULL) { sheet_name = ZSTR_VAL(zs_sheet_name); @@ -498,7 +502,7 @@ PHP_METHOD(vtiful_xls, header) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_ARRAY(header) Z_PARAM_OPTIONAL - Z_PARAM_RESOURCE(zv_format_handle) + Z_PARAM_RESOURCE_OR_NULL(zv_format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -596,8 +600,8 @@ PHP_METHOD(vtiful_xls, insertText) Z_PARAM_LONG(column) Z_PARAM_ZVAL(data) Z_PARAM_OPTIONAL - Z_PARAM_STR(format) - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_STR_OR_NULL(format) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -629,8 +633,8 @@ PHP_METHOD(vtiful_xls, insertDate) Z_PARAM_LONG(column) Z_PARAM_ZVAL(data) Z_PARAM_OPTIONAL - Z_PARAM_STR(format) - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_STR_OR_NULL(format) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -703,9 +707,9 @@ PHP_METHOD(vtiful_xls, insertUrl) Z_PARAM_LONG(column) Z_PARAM_STR(url) Z_PARAM_OPTIONAL - Z_PARAM_STR(text) - Z_PARAM_STR(tool_tip) - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_STR_OR_NULL(text) + Z_PARAM_STR_OR_NULL(tool_tip) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -735,8 +739,8 @@ PHP_METHOD(vtiful_xls, insertImage) Z_PARAM_LONG(column) Z_PARAM_ZVAL(image) Z_PARAM_OPTIONAL - Z_PARAM_DOUBLE(width) - Z_PARAM_DOUBLE(height) + Z_PARAM_DOUBLE_OR_NULL(width, _dummy) + Z_PARAM_DOUBLE_OR_NULL(height, _dummy) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -764,7 +768,7 @@ PHP_METHOD(vtiful_xls, insertFormula) Z_PARAM_LONG(column) Z_PARAM_STR(formula) Z_PARAM_OPTIONAL - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -853,7 +857,7 @@ PHP_METHOD(vtiful_xls, mergeCells) Z_PARAM_STR(range) Z_PARAM_ZVAL(data) Z_PARAM_OPTIONAL - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -886,7 +890,7 @@ PHP_METHOD(vtiful_xls, setColumn) Z_PARAM_STR(range) Z_PARAM_DOUBLE(width) Z_PARAM_OPTIONAL - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -919,7 +923,7 @@ PHP_METHOD(vtiful_xls, setRow) Z_PARAM_STR(range) Z_PARAM_DOUBLE(height) Z_PARAM_OPTIONAL - Z_PARAM_RESOURCE(format_handle) + Z_PARAM_RESOURCE_OR_NULL(format_handle) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -1041,7 +1045,7 @@ PHP_METHOD(vtiful_xls, timestampFromDateDouble) double date = 0; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_DOUBLE(date) + Z_PARAM_DOUBLE_OR_NULL(date, _dummy) ZEND_PARSE_PARAMETERS_END(); if (date <= 0) { @@ -1104,7 +1108,7 @@ PHP_METHOD(vtiful_xls, protection) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STR(password) + Z_PARAM_STR_OR_NULL(password) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -1237,8 +1241,8 @@ PHP_METHOD(vtiful_xls, openSheet) ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STR(zs_sheet_name) - Z_PARAM_LONG(zl_flag) + Z_PARAM_STR_OR_NULL(zs_sheet_name) + Z_PARAM_LONG_OR_NULL(zl_flag, _dummy) ZEND_PARSE_PARAMETERS_END(); ZVAL_COPY(return_value, getThis()); @@ -1348,9 +1352,9 @@ PHP_METHOD(vtiful_xls, putCSV) 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) + Z_PARAM_STRING_OR_NULL(delimiter_str, delimiter_str_len) + Z_PARAM_STRING_OR_NULL(enclosure_str, enclosure_str_len) + Z_PARAM_STRING_OR_NULL(escape_str,escape_str_len) ZEND_PARSE_PARAMETERS_END(); xls_object *obj = Z_XLS_P(getThis()); @@ -1386,9 +1390,9 @@ PHP_METHOD(vtiful_xls, putCSVCallback) 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) + Z_PARAM_STRING_OR_NULL(delimiter_str, delimiter_str_len) + Z_PARAM_STRING_OR_NULL(enclosure_str, enclosure_str_len) + Z_PARAM_STRING_OR_NULL(escape_str,escape_str_len) ZEND_PARSE_PARAMETERS_END(); xls_object *obj = Z_XLS_P(getThis()); @@ -1440,7 +1444,7 @@ PHP_METHOD(vtiful_xls, nextRow) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY(zv_type_t) + Z_PARAM_ARRAY_OR_NULL(zv_type_t) ZEND_PARSE_PARAMETERS_END(); xls_object *obj = Z_XLS_P(getThis()); @@ -1468,7 +1472,7 @@ PHP_METHOD(vtiful_xls, nextCellCallback) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_FUNC(fci, fci_cache) Z_PARAM_OPTIONAL - Z_PARAM_STR(zs_sheet_name) + Z_PARAM_STR_OR_NULL(zs_sheet_name) ZEND_PARSE_PARAMETERS_END(); xls_object *obj = Z_XLS_P(getThis()); diff --git a/kernel/exception.c b/kernel/exception.c index ba47867..dbe3ef6 100644 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -33,3 +33,53 @@ VTIFUL_STARTUP_FUNCTION(exception) { return SUCCESS; } /* }}} */ + +/** {{{ exception_message_map +*/ +char* exception_message_map(int code) { + switch (code) { + case LXW_ERROR_MEMORY_MALLOC_FAILED: + return "Memory error, failed to malloc() required memory."; + case LXW_ERROR_CREATING_XLSX_FILE: + return "Error creating output xlsx file. Usually a permissions error."; + case LXW_ERROR_CREATING_TMPFILE: + return "Error encountered when creating a tmpfile during file assembly."; + case LXW_ERROR_READING_TMPFILE: + return "Error reading a tmpfile."; + case LXW_ERROR_ZIP_FILE_OPERATION: + return "Zlib error with a file operation while creating xlsx file."; + case LXW_ERROR_ZIP_FILE_ADD: + return "Zlib error when adding sub file to xlsx file."; + case LXW_ERROR_ZIP_CLOSE: + return "Zlib error when closing xlsx file."; + case LXW_ERROR_NULL_PARAMETER_IGNORED: + return "NULL function parameter ignored."; + case LXW_ERROR_PARAMETER_VALIDATION: + return "Function parameter validation error."; + case LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED: + return "Worksheet name exceeds Excel's limit of 31 characters."; + case LXW_ERROR_INVALID_SHEETNAME_CHARACTER: + return "Worksheet name contains invalid."; + case LXW_ERROR_SHEETNAME_ALREADY_USED: + return "Worksheet name is already in use."; + case LXW_ERROR_32_STRING_LENGTH_EXCEEDED: + return "Parameter exceeds Excel's limit of 32 characters."; + case LXW_ERROR_128_STRING_LENGTH_EXCEEDED: + return "Parameter exceeds Excel's limit of 128 characters."; + case LXW_ERROR_255_STRING_LENGTH_EXCEEDED: + return "Parameter exceeds Excel's limit of 255 characters."; + case LXW_ERROR_MAX_STRING_LENGTH_EXCEEDED: + return "String exceeds Excel's limit of 32:767 characters."; + case LXW_ERROR_SHARED_STRING_INDEX_NOT_FOUND: + return "Error finding internal string index."; + case LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE: + return "Worksheet row or column index out of range."; + case LXW_ERROR_WORKSHEET_MAX_NUMBER_URLS_EXCEEDED: + return "Maximum number of worksheet URLs (65530) exceeded."; + case LXW_ERROR_IMAGE_DIMENSIONS: + return "Couldn't read image dimensions or DPI."; + default: + return "Unknown error"; + } +} +/* }}} */ \ No newline at end of file diff --git a/kernel/help.c b/kernel/help.c index 4d689c6..fabb3fe 100644 --- a/kernel/help.c +++ b/kernel/help.c @@ -64,7 +64,14 @@ zend_long date_double_to_timestamp(double value) { /* {{{ */ unsigned int directory_exists(const char *path) { zval dir_exists; + +#if PHP_VERSION_ID >= 80100 + zend_string *zs_path = zend_string_init(path, strlen(path), 0); + php_stat(zs_path, FS_IS_DIR, &dir_exists); + zend_string_release(zs_path); +#else php_stat(path, strlen(path), FS_IS_DIR, &dir_exists); +#endif if (Z_TYPE(dir_exists) == IS_FALSE) { zval_ptr_dtor(&dir_exists); @@ -79,7 +86,14 @@ unsigned int directory_exists(const char *path) { /* {{{ */ unsigned int file_exists(const char *path) { zval file_exists; + +#if PHP_VERSION_ID >= 80100 + zend_string *zs_path = zend_string_init(path, strlen(path), 0); + php_stat(zs_path, FS_IS_FILE, &file_exists); + zend_string_release(zs_path); +#else php_stat(path, strlen(path), FS_IS_FILE, &file_exists); +#endif if (Z_TYPE(file_exists) == IS_FALSE) { zval_ptr_dtor(&file_exists); diff --git a/tests/writer_exception.phpt b/tests/writer_exception.phpt new file mode 100644 index 0000000..15b0b14 --- /dev/null +++ b/tests/writer_exception.phpt @@ -0,0 +1,26 @@ +--TEST-- +Check for vtiful presence +--SKIPIF-- + +--FILE-- + './tests']; + + $fileObject = new \Vtiful\Kernel\Excel($config); + + $fileObject->constMemory('tutorial.xlsx', 'DemoSheet') + ->insertText(1, 0, 'viest') + ->insertText(0, 0, 'viest'); + } catch (\Vtiful\Kernel\Exception $exception) { + echo $exception->getCode() . PHP_EOL; + echo $exception->getMessage() . PHP_EOL; + } +?> +--CLEAN-- + +--EXPECT-- +23 +Worksheet row or column index out of range.