diff --git a/LICENSE.txt b/LICENSE.txt index efd03676a20..9d5683673c6 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -85,7 +85,7 @@ PHP Password-compat - MIT - Copyright (c) 2012 Anthony Ferrara - PHPExcel - LGPL - Copyright (c) 2006 - 2014 PHPExcel + PhpSpreadsheet - MIT - Copyright (c) 2019 PhpSpreadsheet Authors Symfony - MIT - Copyright (c) 2004-2013 Fabien Potencier diff --git a/app/bundles/FormBundle/Model/SubmissionModel.php b/app/bundles/FormBundle/Model/SubmissionModel.php index fbb73b9eff5..19f41d6d128 100644 --- a/app/bundles/FormBundle/Model/SubmissionModel.php +++ b/app/bundles/FormBundle/Model/SubmissionModel.php @@ -48,6 +48,8 @@ use Mautic\LeadBundle\Model\LeadModel; use Mautic\LeadBundle\Tracker\Service\DeviceTrackingService\DeviceTrackingServiceInterface; use Mautic\PageBundle\Model\PageModel; +use PhpOffice\PhpSpreadsheet\IOFactory; +use PhpOffice\PhpSpreadsheet\Spreadsheet; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; @@ -557,10 +559,10 @@ function () use ($results, $form, $translator, $viewOnlyFields) { return new Response($content); case 'xlsx': - if (class_exists('PHPExcel')) { + if (class_exists(Spreadsheet::class)) { $response = new StreamedResponse( function () use ($results, $form, $translator, $name, $viewOnlyFields) { - $objPHPExcel = new \PHPExcel(); + $objPHPExcel = new Spreadsheet(); $objPHPExcel->getProperties()->setTitle($name); $objPHPExcel->createSheet(); @@ -612,7 +614,7 @@ function () use ($results, $form, $translator, $name, $viewOnlyFields) { ++$count; } - $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); + $objWriter = IOFactory::createWriter($objPHPExcel, 'Xlsx'); $objWriter->setPreCalculateFormulas(false); $objWriter->save('php://output'); @@ -627,7 +629,7 @@ function () use ($results, $form, $translator, $name, $viewOnlyFields) { return $response; } - throw new \Exception('PHPExcel is required to export to Excel spreadsheets'); + throw new \Exception('PHPSpreadsheet is required to export to Excel spreadsheets'); default: return new Response(); } diff --git a/app/bundles/FormBundle/Views/Result/index.html.php b/app/bundles/FormBundle/Views/Result/index.html.php index eeea0eef783..d2f7f78c9f3 100644 --- a/app/bundles/FormBundle/Views/Result/index.html.php +++ b/app/bundles/FormBundle/Views/Result/index.html.php @@ -8,6 +8,9 @@ * * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html */ + +use PhpOffice\PhpSpreadsheet\Spreadsheet; + $view->extend('MauticCoreBundle:Default:content.html.php'); $view['slots']->set('mauticContent', 'formresult'); $view['slots']->set('headerTitle', $view['translator']->trans('mautic.form.result.header.index', [ @@ -39,7 +42,7 @@ 'primary' => true, ]; -if (class_exists('PHPExcel')) { +if (class_exists(Spreadsheet::class)) { $buttons[] = [ 'attr' => [ 'data-toggle' => '', diff --git a/app/bundles/ReportBundle/Form/Type/ReportType.php b/app/bundles/ReportBundle/Form/Type/ReportType.php index 9248f1abafb..fb8e9a97e87 100644 --- a/app/bundles/ReportBundle/Form/Type/ReportType.php +++ b/app/bundles/ReportBundle/Form/Type/ReportType.php @@ -216,9 +216,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'filters', ReportFiltersType::class, [ - 'type' => FilterSelectorType::class, - 'label' => false, - 'options' => [ + 'entry_type' => FilterSelectorType::class, + 'label' => false, + 'entry_options' => [ 'filterList' => $filters->choices, 'operatorList' => $filters->operatorChoices, 'required' => false, @@ -241,9 +241,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'aggregators', CollectionType::class, [ - 'type' => AggregatorType::class, - 'label' => false, - 'options' => [ + 'entry_type' => AggregatorType::class, + 'label' => false, + 'entry_options' => [ 'columnList' => $groupByColumns->choices, 'required' => false, ], @@ -258,9 +258,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'tableOrder', CollectionType::class, [ - 'type' => TableOrderType::class, - 'label' => false, - 'options' => [ + 'entry_type' => TableOrderType::class, + 'label' => false, + 'entry_options' => [ 'columnList' => $columns->choices, 'required' => false, ], diff --git a/app/bundles/ReportBundle/Model/ExcelExporter.php b/app/bundles/ReportBundle/Model/ExcelExporter.php index dcec2e99b23..8fb1de93a04 100644 --- a/app/bundles/ReportBundle/Model/ExcelExporter.php +++ b/app/bundles/ReportBundle/Model/ExcelExporter.php @@ -12,6 +12,9 @@ namespace Mautic\ReportBundle\Model; use Mautic\CoreBundle\Templating\Helper\FormatterHelper; +use PhpOffice\PhpSpreadsheet\Exception; +use PhpOffice\PhpSpreadsheet\IOFactory; +use PhpOffice\PhpSpreadsheet\Spreadsheet; /** * Class CsvExporter. @@ -35,8 +38,8 @@ public function __construct(FormatterHelper $formatterHelper) */ public function export(array $reportData, $name) { - if (!class_exists('PHPExcel')) { - throw new \Exception('PHPExcel is required to export to Excel spreadsheets'); + if (!class_exists(Spreadsheet::class)) { + throw new \Exception('PHPSpreadsheet is required to export to Excel spreadsheets'); } if (!array_key_exists('data', $reportData) || !array_key_exists('columns', $reportData)) { @@ -44,7 +47,7 @@ public function export(array $reportData, $name) } try { - $objPHPExcel = new \PHPExcel(); + $objPHPExcel = new Spreadsheet(); $objPHPExcel->getProperties()->setTitle($name); $objPHPExcel->createSheet(); @@ -57,7 +60,12 @@ public function export(array $reportData, $name) foreach ($data as $k => $v) { if (0 === $count) { //set the header - $header[] = $k; + foreach ($reportData['columns'] as $c) { + if ($c['alias'] == $k) { + $header[] = $c['label']; + break; + } + } } $row[] = htmlspecialchars_decode($this->formatterHelper->_($v, $reportData['columns'][$reportData['dataColumns'][$k]]['type'], true), ENT_QUOTES); } @@ -73,12 +81,12 @@ public function export(array $reportData, $name) unset($row, $reportData['data'][$count]); } - $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); + $objWriter = IOFactory::createWriter($objPHPExcel, 'Xlsx'); $objWriter->setPreCalculateFormulas(false); $objWriter->save('php://output'); - } catch (\PHPExcel_Exception $e) { - throw new \Exception('PHPExcel Error', 0, $e); + } catch (Exception $e) { + throw new \Exception('PHPSpreadsheet Error', 0, $e); } } } diff --git a/app/bundles/ReportBundle/Model/ReportModel.php b/app/bundles/ReportBundle/Model/ReportModel.php index 1c48d33bfc1..63c975fa951 100644 --- a/app/bundles/ReportBundle/Model/ReportModel.php +++ b/app/bundles/ReportBundle/Model/ReportModel.php @@ -32,6 +32,7 @@ use Mautic\ReportBundle\Generator\ReportGenerator; use Mautic\ReportBundle\Helper\ReportHelper; use Mautic\ReportBundle\ReportEvents; +use PhpOffice\PhpSpreadsheet\Spreadsheet; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Response; @@ -470,8 +471,8 @@ function () use ($reportDataResult) { return new Response($content); case 'xlsx': - if (!class_exists('PHPExcel')) { - throw new \Exception('PHPExcel is required to export to Excel spreadsheets'); + if (!class_exists(Spreadsheet::class)) { + throw new \Exception('PHPSpreadsheet is required to export to Excel spreadsheets'); } $response = new StreamedResponse( diff --git a/app/bundles/ReportBundle/Views/Report/details.html.php b/app/bundles/ReportBundle/Views/Report/details.html.php index 27ebca79a00..04af9c6722e 100644 --- a/app/bundles/ReportBundle/Views/Report/details.html.php +++ b/app/bundles/ReportBundle/Views/Report/details.html.php @@ -8,6 +8,9 @@ * * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html */ + +use PhpOffice\PhpSpreadsheet\Spreadsheet; + $header = $view['translator']->trans( 'mautic.report.report.header.view', ['%name%' => $view->escape($view['translator']->trans($report->getName()))] @@ -52,7 +55,7 @@ 'iconClass' => 'fa fa-file-text-o', ]; - if (class_exists('PHPExcel')) { + if (class_exists(Spreadsheet::class)) { $buttons[] = [ 'attr' => [ 'data-toggle' => 'download', @@ -94,7 +97,7 @@ ], 'routeBase' => 'report', 'langVar' => 'report.report', - 'postCustomButtons' => $buttons, + 'customButtons' => $buttons, ] ) ); diff --git a/composer.json b/composer.json index bf3d78f16c6..885f3223a2f 100644 --- a/composer.json +++ b/composer.json @@ -76,11 +76,11 @@ "friendsofsymfony/rest-bundle": "~2.6.0", "friendsofsymfony/oauth-server-bundle": "~1.6.0", "willdurand/oauth-server-bundle": "dev-release-0.0.3", - "oneup/uploader-bundle": "~2.0", "jms/serializer-bundle": "~3.5.0", - "phpoffice/phpexcel": "1.8.1", "joomla/http": "~1.3.3", "joomla/filter": "~1.3.5", + "oneup/uploader-bundle": "~2.0", + "phpoffice/phpspreadsheet": "^1.10", "mrclay/minify": "2.2.0", "jbroadway/urlify": "^1.0", "geoip2/geoip2": "~2.0", diff --git a/composer.lock b/composer.lock index 0ef148a49ad..2a7faa72e6c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,30 +4,30 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "185355d82378aed80c362960d83702cc", + "content-hash": "8d359d30792649a30fa1a553e3ca4b0c", "packages": [ { "name": "aws/aws-sdk-php", - "version": "3.130.3", + "version": "3.132.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "916356edb5c30fa564d02de94bde51a9c0bb4469" + "reference": "d1ea3332539a07d122e5cf397c0eb3a1fb75eede" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/916356edb5c30fa564d02de94bde51a9c0bb4469", - "reference": "916356edb5c30fa564d02de94bde51a9c0bb4469", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d1ea3332539a07d122e5cf397c0eb3a1fb75eede", + "reference": "d1ea3332539a07d122e5cf397c0eb3a1fb75eede", "shasum": "" }, "require": { "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^5.3.3|^6.2.1", - "guzzlehttp/promises": "~1.0", + "guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0", + "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.4.1", - "mtdowling/jmespath.php": "~2.2", + "mtdowling/jmespath.php": "^2.5", "php": ">=5.5" }, "require-dev": { @@ -88,7 +88,7 @@ "s3", "sdk" ], - "time": "2020-01-02T19:13:50+00:00" + "time": "2020-01-07T19:13:51+00:00" }, { "name": "clue/stream-filter", @@ -4317,6 +4317,170 @@ "homepage": "http://www.lightsaml.com", "time": "2018-05-23T08:11:59+00:00" }, + { + "name": "markbaker/complex", + "version": "1.4.7", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpcompatibility/php-compatibility": "^8.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "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" + ] + }, + "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": "2018-10-13T23:28:42+00:00" + }, + { + "name": "markbaker/matrix", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/5348c5a67e3b75cd209d70103f916a93b1f1ed21", + "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21", + "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", + "sebastian/phpcpd": "^3.0", + "squizlabs/php_codesniffer": "^3.0@dev" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + }, + "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" + ] + }, + "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": "2019-10-06T11:29:25+00:00" + }, { "name": "maxmind-db/reader", "version": "v1.6.0", @@ -5604,62 +5768,97 @@ "time": "2016-01-26T13:27:02+00:00" }, { - "name": "phpoffice/phpexcel", - "version": "1.8.1", + "name": "phpoffice/phpspreadsheet", + "version": "1.10.1", "source": { "type": "git", - "url": "https://github.com/PHPOffice/PHPExcel.git", - "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32" + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "1648dc9ebef6ebe0c5a172e16cf66732918416e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/372c7cbb695a6f6f1e62649381aeaa37e7e70b32", - "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/1648dc9ebef6ebe0c5a172e16cf66732918416e0", + "reference": "1648dc9ebef6ebe0c5a172e16cf66732918416e0", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", "ext-xml": "*", + "ext-xmlreader": "*", "ext-xmlwriter": "*", - "php": ">=5.2.0" + "ext-zip": "*", + "ext-zlib": "*", + "markbaker/complex": "^1.4", + "markbaker/matrix": "^1.2", + "php": "^7.1", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "dompdf/dompdf": "^0.8.3", + "friendsofphp/php-cs-fixer": "^2.16", + "jpgraph/jpgraph": "^4.0", + "mpdf/mpdf": "^8.0", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5", + "tecnickcom/tcpdf": "^6.3" + }, + "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" }, "type": "library", "autoload": { - "psr-0": { - "PHPExcel": "Classes/" + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL" + "MIT" ], "authors": [ { "name": "Maarten Balliauw", - "homepage": "http://blog.maartenballiauw.be" + "homepage": "https://blog.maartenballiauw.be" }, { - "name": "Mark Baker" + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" }, { "name": "Franck Lefevre", - "homepage": "http://blog.rootslabs.net" + "homepage": "https://rootslabs.net" }, { "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" } ], - "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "http://phpexcel.codeplex.com", + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", "keywords": [ "OpenXML", "excel", + "gnumeric", + "ods", "php", "spreadsheet", "xls", "xlsx" ], - "abandoned": "phpoffice/phpspreadsheet", - "time": "2015-05-01T07:00:55+00:00" + "time": "2019-12-01T23:13:51+00:00" }, { "name": "phpseclib/phpseclib", @@ -12199,16 +12398,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.5.18", + "version": "7.5.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "fcf6c4bfafaadc07785528b06385cce88935474d" + "reference": "4263f76a3fc65385e242ef7357b99f3bed36707e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fcf6c4bfafaadc07785528b06385cce88935474d", - "reference": "fcf6c4bfafaadc07785528b06385cce88935474d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4263f76a3fc65385e242ef7357b99f3bed36707e", + "reference": "4263f76a3fc65385e242ef7357b99f3bed36707e", "shasum": "" }, "require": { @@ -12279,7 +12478,7 @@ "testing", "xunit" ], - "time": "2019-12-06T05:14:37+00:00" + "time": "2020-01-06T16:53:05+00:00" }, { "name": "phpunit/phpunit-selenium",