diff --git a/.distignore b/.distignore index ab251165..3986af78 100755 --- a/.distignore +++ b/.distignore @@ -17,8 +17,9 @@ artifact composer.json composer.lock package-lock.json -vendor/phpoffice/phpspreadsheet/samples -vendor/phpoffice/phpspreadsheet/docs +vendor/openspout/openspout/LICENSE-for-* +vendor/openspout/openspout/UPGRADE-3.0.md +vendor/openspout/openspout/README.md cypress cypress.json .github diff --git a/classes/Visualizer/Module.php b/classes/Visualizer/Module.php index 5604ea5d..8ef678c1 100644 --- a/classes/Visualizer/Module.php +++ b/classes/Visualizer/Module.php @@ -235,7 +235,6 @@ public function _getDataAs( $chart_id, $type ) { } $filename = $title; - switch ( $type ) { case 'csv': $final = $this->_getCSV( $rows, $filename, false ); @@ -324,9 +323,9 @@ private function _getCSV( $rows, $filename, $enclose ) { * @param string $filename The name of the file to use. */ private function _getExcel( $rows, $filename ) { - // PHPExcel did not like sheet names longer than 31 characters and we will assume the same with PhpSpreadsheet - $chart = substr( $filename, 0, 30 ); - $filename .= '.xlsx'; + // OpenSpout allows for long sheet names, but let's keep the same limit for compatibility. + $chart = substr( $filename, 0, 30 ); + $filename .= '.xlsx'; if ( ! apply_filters( 'vizualizer_export_include_series_type', true ) ) { unset( $rows[1] ); $rows = array_values( $rows ); @@ -339,22 +338,32 @@ function( $r ) { } $vendor_file = VISUALIZER_ABSPATH . '/vendor/autoload.php'; if ( is_readable( $vendor_file ) ) { - include_once( $vendor_file ); - } - $xlsData = ''; - if ( class_exists( 'PhpOffice\PhpSpreadsheet\Spreadsheet' ) ) { - $doc = new PhpOffice\PhpSpreadsheet\Spreadsheet(); - $doc->getActiveSheet()->fromArray( $rows, null, 'A1' ); - $doc->getActiveSheet()->setTitle( sanitize_title( $chart ) ); - $doc = apply_filters( 'visualizer_excel_doc', $doc ); - $writer = PhpOffice\PhpSpreadsheet\IOFactory::createWriter( $doc, 'Xlsx' ); - ob_start(); - $writer->save( 'php://output' ); - $xlsData = ob_get_contents(); - ob_end_clean(); + include_once $vendor_file; + } + $xlsData = ''; + if ( class_exists( 'OpenSpout\Writer\Common\Creator\WriterEntityFactory' ) ) { + try { + // Use OpenSpout to create the XLSX file in memory. + $writer = \OpenSpout\Writer\Common\Creator\WriterEntityFactory::createXLSXWriter(); + $writer->openToFile( 'php://output' ); // Open to output instead of a file. + $writer->getCurrentSheet()->setName( sanitize_title( $chart ) ); + + // Write rows. + foreach ( $rows as $row ) { + $rowFromValues = \OpenSpout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray( $row ); + $writer->addRow( $rowFromValues ); + } + + ob_start(); + $writer->close(); // Saves and closes the file in the output buffer. + $xlsData = ob_get_clean(); + } catch ( Exception $e ) { + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'OpenSpout writer error: ' . $e->getMessage(), 'error', __FILE__, __LINE__ ); + error_log( 'OpenSpout writer error: ' . $e->getMessage() ); + } } else { - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Class PhpOffice\PhpSpreadsheet\Spreadsheet does not exist!', 'error', __FILE__, __LINE__ ); - error_log( 'Class PhpOffice\PhpSpreadsheet\Spreadsheet does not exist!' ); + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Class OpenSpout\Writer\Common\Creator\WriterEntityFactory does not exist!', 'error', __FILE__, __LINE__ ); + error_log( 'Class OpenSpout\Writer\Common\Creator\WriterEntityFactory does not exist!' ); } return array( 'csv' => 'data:application/vnd.ms-excel;base64,' . base64_encode( $xlsData ), diff --git a/classes/Visualizer/Render/Sidebar.php b/classes/Visualizer/Render/Sidebar.php index 5f8cbb9f..702d1a69 100644 --- a/classes/Visualizer/Render/Sidebar.php +++ b/classes/Visualizer/Render/Sidebar.php @@ -270,7 +270,7 @@ private static function is_excel_enabled() { return false; } - return class_exists( 'PhpOffice\PhpSpreadsheet\Spreadsheet' ) && extension_loaded( 'zip' ) && extension_loaded( 'xml' ) && extension_loaded( 'fileinfo' ); + return class_exists( 'OpenSpout\Writer\Common\Creator\WriterEntityFactory' ) && extension_loaded( 'zip' ) && extension_loaded( 'xml' ) && extension_loaded( 'fileinfo' ); } /** diff --git a/composer.json b/composer.json index 87179b8b..bfa3e1a2 100644 --- a/composer.json +++ b/composer.json @@ -22,13 +22,12 @@ }, "require": { "codeinwp/themeisle-sdk": "^3.3", - "phpoffice/phpspreadsheet": "1.8.2", - "neitanod/forceutf8": "~2.0" + "neitanod/forceutf8": "~2.0", + "openspout/openspout": "^3.7" }, "autoload": { "files": [ - "vendor/codeinwp/themeisle-sdk/load.php", - "vendor/phpoffice/phpspreadsheet/src/Bootstrap.php" + "vendor/codeinwp/themeisle-sdk/load.php" ] }, "scripts": { @@ -40,7 +39,7 @@ "config": { "optimize-autoloader": true, "platform": { - "php": "5.6" + "php": "7.4" }, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true diff --git a/composer.lock b/composer.lock index a191b6c6..07868713 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b1c4972cf7a69e915c83661005512e70", + "content-hash": "7000266e616112b1392930052784add1", "packages": [ { "name": "codeinwp/themeisle-sdk", @@ -47,170 +47,6 @@ }, "time": "2024-10-25T07:28:34+00:00" }, - { - "name": "markbaker/complex", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/MarkBaker/PHPComplex.git", - "reference": "c3131244e29c08d44fefb49e0dd35021e9e39dd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/c3131244e29c08d44fefb49e0dd35021e9e39dd2", - "reference": "c3131244e29c08d44fefb49e0dd35021e9e39dd2", - "shasum": "" - }, - "require": { - "php": "^5.6.0|^7.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", - "phpcompatibility/php-compatibility": "^9.0", - "phpdocumentor/phpdocumentor": "2.*", - "phploc/phploc": "^4.0|^5.0|^6.0|^7.0", - "phpmd/phpmd": "2.*", - "phpunit/phpunit": "^4.8.35|^5.0|^6.0|^7.0", - "sebastian/phpcpd": "2.*", - "squizlabs/php_codesniffer": "^3.4.0" - }, - "type": "library", - "autoload": { - "files": [ - "classes/src/functions/abs.php", - "classes/src/functions/acos.php", - "classes/src/functions/acosh.php", - "classes/src/functions/acot.php", - "classes/src/functions/acoth.php", - "classes/src/functions/acsc.php", - "classes/src/functions/acsch.php", - "classes/src/functions/argument.php", - "classes/src/functions/asec.php", - "classes/src/functions/asech.php", - "classes/src/functions/asin.php", - "classes/src/functions/asinh.php", - "classes/src/functions/atan.php", - "classes/src/functions/atanh.php", - "classes/src/functions/conjugate.php", - "classes/src/functions/cos.php", - "classes/src/functions/cosh.php", - "classes/src/functions/cot.php", - "classes/src/functions/coth.php", - "classes/src/functions/csc.php", - "classes/src/functions/csch.php", - "classes/src/functions/exp.php", - "classes/src/functions/inverse.php", - "classes/src/functions/ln.php", - "classes/src/functions/log2.php", - "classes/src/functions/log10.php", - "classes/src/functions/negative.php", - "classes/src/functions/pow.php", - "classes/src/functions/rho.php", - "classes/src/functions/sec.php", - "classes/src/functions/sech.php", - "classes/src/functions/sin.php", - "classes/src/functions/sinh.php", - "classes/src/functions/sqrt.php", - "classes/src/functions/tan.php", - "classes/src/functions/tanh.php", - "classes/src/functions/theta.php", - "classes/src/operations/add.php", - "classes/src/operations/subtract.php", - "classes/src/operations/multiply.php", - "classes/src/operations/divideby.php", - "classes/src/operations/divideinto.php" - ], - "psr-4": { - "Complex\\": "classes/src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Baker", - "email": "mark@lange.demon.co.uk" - } - ], - "description": "PHP Class for working with complex numbers", - "homepage": "https://github.com/MarkBaker/PHPComplex", - "keywords": [ - "complex", - "mathematics" - ], - "time": "2020-08-26T19:47:57+00:00" - }, - { - "name": "markbaker/matrix", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/MarkBaker/PHPMatrix.git", - "reference": "44bb1ab01811116f01fe216ab37d921dccc6c10d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/44bb1ab01811116f01fe216ab37d921dccc6c10d", - "reference": "44bb1ab01811116f01fe216ab37d921dccc6c10d", - "shasum": "" - }, - "require": { - "php": "^5.6.0|^7.0.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", - "phpcompatibility/php-compatibility": "dev-master", - "phploc/phploc": "^4", - "phpmd/phpmd": "dev-master", - "phpunit/phpunit": "^5.7|^6.0|7.0", - "sebastian/phpcpd": "^3.0", - "squizlabs/php_codesniffer": "^3.0@dev" - }, - "type": "library", - "autoload": { - "files": [ - "classes/src/Functions/adjoint.php", - "classes/src/Functions/antidiagonal.php", - "classes/src/Functions/cofactors.php", - "classes/src/Functions/determinant.php", - "classes/src/Functions/diagonal.php", - "classes/src/Functions/identity.php", - "classes/src/Functions/inverse.php", - "classes/src/Functions/minors.php", - "classes/src/Functions/trace.php", - "classes/src/Functions/transpose.php", - "classes/src/Operations/add.php", - "classes/src/Operations/directsum.php", - "classes/src/Operations/subtract.php", - "classes/src/Operations/multiply.php", - "classes/src/Operations/divideby.php", - "classes/src/Operations/divideinto.php" - ], - "psr-4": { - "Matrix\\": "classes/src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Baker", - "email": "mark@lange.demon.co.uk" - } - ], - "description": "PHP Class for working with matrices", - "homepage": "https://github.com/MarkBaker/PHPMatrix", - "keywords": [ - "mathematics", - "matrix", - "vector" - ], - "time": "2021-01-26T14:36:01+00:00" - }, { "name": "neitanod/forceutf8", "version": "v2.0.4", @@ -249,146 +85,93 @@ "time": "2019-12-10T14:09:14+00:00" }, { - "name": "phpoffice/phpspreadsheet", - "version": "1.8.2", + "name": "openspout/openspout", + "version": "v3.7.4", "source": { "type": "git", - "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "0c1346a1956347590b7db09533966307d20cb7cc" + "url": "https://github.com/openspout/openspout.git", + "reference": "dfbbd53b5edcd486b45a37f6a04fac33073c70f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/0c1346a1956347590b7db09533966307d20cb7cc", - "reference": "0c1346a1956347590b7db09533966307d20cb7cc", + "url": "https://api.github.com/repos/openspout/openspout/zipball/dfbbd53b5edcd486b45a37f6a04fac33073c70f3", + "reference": "dfbbd53b5edcd486b45a37f6a04fac33073c70f3", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-dom": "*", - "ext-fileinfo": "*", - "ext-gd": "*", - "ext-iconv": "*", + "ext-filter": "*", "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-xml": "*", "ext-xmlreader": "*", - "ext-xmlwriter": "*", "ext-zip": "*", - "ext-zlib": "*", - "markbaker/complex": "^1.4", - "markbaker/matrix": "^1.1", - "php": "^5.6|^7.0", - "psr/simple-cache": "^1.0" + "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" }, "require-dev": { - "doctrine/instantiator": "^1.0.0", - "dompdf/dompdf": "^0.8.0", - "friendsofphp/php-cs-fixer": "@stable", - "jpgraph/jpgraph": "^4.0", - "mpdf/mpdf": "^7.0.0", - "phpcompatibility/php-compatibility": "^8.0", - "phpunit/phpunit": "^5.7", - "squizlabs/php_codesniffer": "^3.3", - "tecnickcom/tcpdf": "^6.2" + "ext-zlib": "*", + "friendsofphp/php-cs-fixer": "^3.4", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" }, "suggest": { - "dompdf/dompdf": "Option for rendering PDF with PDF Writer", - "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", - "mpdf/mpdf": "Option for rendering PDF with PDF Writer", - "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + "ext-iconv": "To handle non UTF-8 CSV files (if \"php-intl\" is not already installed or is too limited)", + "ext-intl": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3.x-dev" + } + }, "autoload": { "psr-4": { - "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + "OpenSpout\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1-or-later" + "MIT" ], "authors": [ { - "name": "Erik Tilt" - }, - { - "name": "Adrien Crivelli" - }, - { - "name": "Maarten Balliauw", - "homepage": "https://blog.maartenballiauw.be" - }, - { - "name": "Mark Baker", - "homepage": "https://markbakeruk.net" - }, - { - "name": "Franck Lefevre", - "homepage": "https://rootslabs.net" + "name": "Adrien Loison", + "email": "adrien@box.com" } ], - "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "description": "PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way", + "homepage": "https://github.com/openspout/openspout", "keywords": [ - "OpenXML", + "OOXML", + "csv", "excel", - "gnumeric", + "memory", + "odf", "ods", + "office", + "open", "php", + "read", + "scale", "spreadsheet", - "xls", + "stream", + "write", "xlsx" ], - "time": "2019-07-08T21:21:25+00:00" - }, - { - "name": "psr/simple-cache", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } + "support": { + "issues": "https://github.com/openspout/openspout/issues", + "source": "https://github.com/openspout/openspout/tree/v3.7.4" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ + { + "url": "https://paypal.me/filippotessarotto", + "type": "custom" + }, { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "url": "https://github.com/Slamdunk", + "type": "github" } ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "time": "2017-10-23T01:57:42+00:00" + "time": "2022-03-31T06:15:15+00:00" } ], "packages-dev": [ @@ -805,7 +588,7 @@ "platform": [], "platform-dev": [], "platform-overrides": { - "php": "5.6" + "php": "7.4" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" }