From d98b7fe630b89ced4ca90dd2595e04cefc172a87 Mon Sep 17 00:00:00 2001 From: gongfuxiang Date: Mon, 21 Nov 2022 15:06:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=95=E5=B1=82=E6=A1=86=E6=9E=B6=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E5=88=B0tp6.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common.php | 3 +- composer.lock | 421 ++---- vendor/composer/autoload_files.php | 8 +- vendor/composer/autoload_psr4.php | 6 +- vendor/composer/autoload_static.php | 39 +- vendor/composer/installed.json | 461 ++----- vendor/composer/installed.php | 94 +- vendor/ezyang/htmlpurifier/CHANGELOG.md | 6 + vendor/ezyang/htmlpurifier/VERSION | 2 +- vendor/ezyang/htmlpurifier/composer.json | 23 +- .../library/HTMLPurifier.includes.php | 3 +- .../htmlpurifier/library/HTMLPurifier.php | 6 +- .../library/HTMLPurifier.safe-includes.php | 1 + .../AttrDef/HTML/ContentEditable.php | 16 + .../HTMLPurifier/AttrTransform/NameSync.php | 5 + .../HTMLPurifier/AttrTransform/SafeParam.php | 5 + .../library/HTMLPurifier/AttrTypes.php | 1 + .../library/HTMLPurifier/ChildDef/List.php | 2 + .../library/HTMLPurifier/Config.php | 2 +- .../library/HTMLPurifier/ElementDef.php | 2 +- .../library/HTMLPurifier/Encoder.php | 8 +- .../HTMLModule/CommonAttributes.php | 1 + .../Injector/RemoveSpansWithoutAttributes.php | 15 +- .../library/HTMLPurifier/Length.php | 2 +- .../library/HTMLPurifier/Lexer.php | 9 +- .../library/HTMLPurifier/Lexer/PH5P.php | 2 +- .../HTMLPurifier/PropertyListIterator.php | 1 + .../library/HTMLPurifier/StringHash.php | 1 + .../HTMLPurifier/URIFilter/HostBlacklist.php | 2 +- .../library/HTMLPurifier/URIFilter/Munge.php | 10 +- .../flysystem-cached-adapter/.editorconfig | 10 - .../flysystem-cached-adapter/.gitignore | 4 - .../league/flysystem-cached-adapter/.php_cs | 7 - .../flysystem-cached-adapter/.scrutinizer.yml | 34 - .../flysystem-cached-adapter/.travis.yml | 29 - .../league/flysystem-cached-adapter/LICENSE | 19 - .../clover/.gitignore | 2 - .../flysystem-cached-adapter/composer.json | 30 - .../flysystem-cached-adapter/phpspec.yml | 6 - .../flysystem-cached-adapter/phpunit.php | 3 - .../flysystem-cached-adapter/phpunit.xml | 29 - .../league/flysystem-cached-adapter/readme.md | 20 - .../spec/CachedAdapterSpec.php | 435 ------ .../src/CacheInterface.php | 101 -- .../src/CachedAdapter.php | 346 ----- .../src/Storage/AbstractCache.php | 418 ------ .../src/Storage/Adapter.php | 115 -- .../src/Storage/Memcached.php | 59 - .../src/Storage/Memory.php | 22 - .../src/Storage/Noop.php | 171 --- .../src/Storage/PhpRedis.php | 62 - .../src/Storage/Predis.php | 75 - .../src/Storage/Psr6Cache.php | 59 - .../src/Storage/Stash.php | 60 - .../tests/AdapterCacheTests.php | 104 -- .../tests/InspectionTests.php | 16 - .../tests/MemcachedTests.php | 35 - .../tests/MemoryCacheTests.php | 255 ---- .../tests/NoopCacheTests.php | 35 - .../tests/PhpRedisTests.php | 45 - .../tests/PredisTests.php | 55 - .../tests/Psr6CacheTest.php | 45 - .../tests/StashTest.php | 43 - vendor/league/flysystem/CODE_OF_CONDUCT.md | 76 - vendor/league/flysystem/LICENSE | 19 - vendor/league/flysystem/SECURITY.md | 16 - vendor/league/flysystem/composer.json | 68 - vendor/league/flysystem/deprecations.md | 19 - .../flysystem/src/Adapter/AbstractAdapter.php | 72 - .../src/Adapter/AbstractFtpAdapter.php | 705 ---------- .../src/Adapter/CanOverwriteFiles.php | 12 - vendor/league/flysystem/src/Adapter/Ftp.php | 584 -------- vendor/league/flysystem/src/Adapter/Ftpd.php | 48 - vendor/league/flysystem/src/Adapter/Local.php | 533 ------- .../flysystem/src/Adapter/NullAdapter.php | 144 -- .../Polyfill/NotSupportingVisibilityTrait.php | 33 - .../Adapter/Polyfill/StreamedCopyTrait.php | 51 - .../Adapter/Polyfill/StreamedReadingTrait.php | 44 - .../src/Adapter/Polyfill/StreamedTrait.php | 9 - .../Adapter/Polyfill/StreamedWritingTrait.php | 60 - .../flysystem/src/Adapter/SynologyFtp.php | 8 - .../league/flysystem/src/AdapterInterface.php | 118 -- vendor/league/flysystem/src/Config.php | 107 -- .../league/flysystem/src/ConfigAwareTrait.php | 49 - .../src/ConnectionErrorException.php | 9 - .../src/ConnectionRuntimeException.php | 9 - .../flysystem/src/CorruptedPathDetected.php | 17 - vendor/league/flysystem/src/Directory.php | 31 - vendor/league/flysystem/src/Exception.php | 8 - vendor/league/flysystem/src/File.php | 205 --- .../flysystem/src/FileExistsException.php | 37 - .../flysystem/src/FileNotFoundException.php | 37 - vendor/league/flysystem/src/Filesystem.php | 409 ------ .../flysystem/src/FilesystemException.php | 7 - .../flysystem/src/FilesystemInterface.php | 284 ---- .../src/FilesystemNotFoundException.php | 12 - vendor/league/flysystem/src/Handler.php | 137 -- .../flysystem/src/InvalidRootException.php | 9 - vendor/league/flysystem/src/MountManager.php | 648 --------- .../flysystem/src/NotSupportedException.php | 37 - .../flysystem/src/Plugin/AbstractPlugin.php | 24 - .../league/flysystem/src/Plugin/EmptyDir.php | 34 - .../flysystem/src/Plugin/ForcedCopy.php | 44 - .../flysystem/src/Plugin/ForcedRename.php | 44 - .../flysystem/src/Plugin/GetWithMetadata.php | 51 - .../league/flysystem/src/Plugin/ListFiles.php | 35 - .../league/flysystem/src/Plugin/ListPaths.php | 36 - .../league/flysystem/src/Plugin/ListWith.php | 60 - .../flysystem/src/Plugin/PluggableTrait.php | 97 -- .../src/Plugin/PluginNotFoundException.php | 10 - .../league/flysystem/src/PluginInterface.php | 20 - vendor/league/flysystem/src/ReadInterface.php | 88 -- .../flysystem/src/RootViolationException.php | 10 - vendor/league/flysystem/src/SafeStorage.php | 39 - .../flysystem/src/UnreadableFileException.php | 18 - vendor/league/flysystem/src/Util.php | 354 ----- .../src/Util/ContentListingFormatter.php | 122 -- vendor/league/flysystem/src/Util/MimeType.php | 80 -- .../flysystem/src/Util/StreamHasher.php | 36 - .../league/mime-type-detection/CHANGELOG.md | 31 - vendor/league/mime-type-detection/LICENSE | 19 - .../league/mime-type-detection/composer.json | 34 - .../src/EmptyExtensionToMimeTypeMap.php | 13 - .../src/ExtensionMimeTypeDetector.php | 42 - .../src/ExtensionToMimeTypeMap.php | 10 - .../src/FinfoMimeTypeDetector.php | 92 -- .../src/GeneratedExtensionToMimeTypeMap.php | 1227 ----------------- .../src/MimeTypeDetector.php | 19 - .../src/OverridingExtensionToMimeTypeMap.php | 30 - .../phpspreadsheet/.php-cs-fixer.dist.php | 2 +- vendor/phpoffice/phpspreadsheet/CHANGELOG.md | 103 ++ vendor/phpoffice/phpspreadsheet/README.md | 14 +- vendor/phpoffice/phpspreadsheet/composer.json | 15 +- .../phpspreadsheet/phpstan-baseline.neon | 1143 +-------------- .../phpspreadsheet/phpstan.neon.dist | 8 +- .../Calculation/Calculation.php | 33 +- .../Calculation/Engine/Logger.php | 6 +- .../Calculation/Engineering/Compare.php | 4 +- .../Calculation/Engineering/ConvertUOM.php | 1 + .../Calculation/FormulaParser.php | 2 +- .../PhpSpreadsheet/Calculation/Functions.php | 24 +- .../Calculation/Information/ErrorValue.php | 2 +- .../Calculation/Information/ExcelError.php | 33 +- .../Calculation/Information/Value.php | 2 +- .../Calculation/LookupRef/Address.php | 7 +- .../Calculation/LookupRef/HLookup.php | 2 +- .../Calculation/LookupRef/Helpers.php | 10 +- .../Calculation/LookupRef/Indirect.php | 9 +- .../Calculation/LookupRef/LookupBase.php | 12 +- .../Calculation/LookupRef/Offset.php | 11 + .../Calculation/LookupRef/VLookup.php | 6 +- .../Calculation/MathTrig/Random.php | 2 +- .../Calculation/Statistical/Averages.php | 2 +- .../Statistical/Distributions/ChiSquared.php | 2 +- .../Calculation/TextData/Extract.php | 182 +++ .../Calculation/TextData/Format.php | 34 + .../Calculation/TextData/Text.php | 174 +++ .../Calculation/locale/Translations.xlsx | Bin 110548 -> 111436 bytes .../Calculation/locale/da/functions | 1 + .../Calculation/locale/de/functions | 1 + .../Calculation/locale/es/functions | 1 + .../Calculation/locale/fi/functions | 1 + .../Calculation/locale/fr/functions | 1 + .../Calculation/locale/hu/functions | 1 + .../Calculation/locale/nb/functions | 1 + .../Calculation/locale/nl/functions | 1 + .../Calculation/locale/pt/br/functions | 1 + .../Calculation/locale/pt/functions | 1 + .../Calculation/locale/sv/functions | 1 + .../src/PhpSpreadsheet/Cell/AddressHelper.php | 29 +- .../src/PhpSpreadsheet/Cell/Cell.php | 102 +- .../src/PhpSpreadsheet/Cell/Coordinate.php | 21 +- .../src/PhpSpreadsheet/Chart/Axis.php | 35 +- .../src/PhpSpreadsheet/Chart/Chart.php | 58 +- .../src/PhpSpreadsheet/Chart/ChartColor.php | 32 +- .../src/PhpSpreadsheet/Chart/DataSeries.php | 2 +- .../PhpSpreadsheet/Chart/DataSeriesValues.php | 27 +- .../src/PhpSpreadsheet/Chart/Layout.php | 56 + .../src/PhpSpreadsheet/Chart/PlotArea.php | 62 + .../PhpSpreadsheet/Chart/Renderer/JpGraph.php | 862 +----------- .../Chart/Renderer/JpGraphRendererBase.php | 852 ++++++++++++ .../Chart/Renderer/MtJpGraphRenderer.php | 36 + .../Chart/Renderer/PHP Charting Libraries.txt | 7 +- .../src/PhpSpreadsheet/Chart/TrendLine.php | 226 +++ .../src/PhpSpreadsheet/Collection/Cells.php | 20 +- .../Collection/CellsFactory.php | 3 +- .../{Memory.php => Memory/SimpleCache1.php} | 7 +- .../Collection/Memory/SimpleCache3.php | 109 ++ .../src/PhpSpreadsheet/DefinedName.php | 2 +- .../src/PhpSpreadsheet/Helper/Dimension.php | 14 +- .../src/PhpSpreadsheet/Helper/Sample.php | 30 +- .../src/PhpSpreadsheet/Helper/TextGrid.php | 139 ++ .../src/PhpSpreadsheet/Reader/Gnumeric.php | 2 +- .../src/PhpSpreadsheet/Reader/Html.php | 23 +- .../src/PhpSpreadsheet/Reader/Ods.php | 3 +- .../Reader/Security/XmlScanner.php | 2 +- .../src/PhpSpreadsheet/Reader/Xls.php | 4 +- .../src/PhpSpreadsheet/Reader/Xlsx.php | 96 +- .../PhpSpreadsheet/Reader/Xlsx/AutoFilter.php | 26 +- .../Reader/Xlsx/BaseParserClass.php | 5 +- .../src/PhpSpreadsheet/Reader/Xlsx/Chart.php | 223 ++- .../Reader/Xlsx/ColumnAndRowAttributes.php | 12 +- .../Reader/Xlsx/ConditionalStyles.php | 22 +- .../Reader/Xlsx/DataValidations.php | 4 +- .../PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php | 2 + .../PhpSpreadsheet/Reader/Xlsx/PageSetup.php | 17 +- .../Reader/Xlsx/SheetViewOptions.php | 11 +- .../Reader/Xlsx/WorkbookView.php | 2 +- .../src/PhpSpreadsheet/Reader/Xml.php | 3 +- .../src/PhpSpreadsheet/ReferenceHelper.php | 51 +- .../src/PhpSpreadsheet/Settings.php | 10 +- .../src/PhpSpreadsheet/Shared/Font.php | 538 +++----- .../Shared/JAMA/EigenvalueDecomposition.php | 6 +- .../src/PhpSpreadsheet/Shared/JAMA/Matrix.php | 81 +- .../JAMA/SingularValueDecomposition.php | 6 +- .../PhpSpreadsheet/Shared/StringHelper.php | 34 +- .../src/PhpSpreadsheet/Spreadsheet.php | 48 +- .../src/PhpSpreadsheet/Style/Alignment.php | 69 +- .../src/PhpSpreadsheet/Style/Color.php | 2 - .../ConditionalDataBar.php | 21 +- .../src/PhpSpreadsheet/Style/Font.php | 8 +- .../NumberFormat/PercentageFormatter.php | 12 +- .../PhpSpreadsheet/Worksheet/CellIterator.php | 1 + .../PhpSpreadsheet/Worksheet/PageSetup.php | 9 +- .../PhpSpreadsheet/Worksheet/Worksheet.php | 154 ++- .../src/PhpSpreadsheet/Writer/Html.php | 246 ++-- .../src/PhpSpreadsheet/Writer/IWriter.php | 2 + .../src/PhpSpreadsheet/Writer/Pdf/Dompdf.php | 13 +- .../src/PhpSpreadsheet/Writer/Pdf/Mpdf.php | 3 + .../src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php | 2 +- .../src/PhpSpreadsheet/Writer/Xls.php | 2 - .../src/PhpSpreadsheet/Writer/Xls/Parser.php | 9 +- .../PhpSpreadsheet/Writer/Xls/Worksheet.php | 14 +- .../src/PhpSpreadsheet/Writer/Xlsx.php | 8 +- .../src/PhpSpreadsheet/Writer/Xlsx/Chart.php | 302 +++- .../PhpSpreadsheet/Writer/Xlsx/Comments.php | 6 +- .../Writer/Xlsx/DefinedNames.php | 2 +- .../PhpSpreadsheet/Writer/Xlsx/DocProps.php | 6 +- .../src/PhpSpreadsheet/Writer/Xlsx/Rels.php | 7 +- .../Writer/Xlsx/StringTable.php | 54 +- .../src/PhpSpreadsheet/Writer/Xlsx/Style.php | 135 +- .../PhpSpreadsheet/Writer/Xlsx/Workbook.php | 14 +- .../PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 177 +-- .../src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php | 3 + vendor/psr/cache/CHANGELOG.md | 16 - vendor/psr/cache/LICENSE.txt | 19 - vendor/psr/cache/README.md | 9 - vendor/psr/cache/composer.json | 25 - vendor/psr/cache/src/CacheException.php | 10 - vendor/psr/cache/src/CacheItemInterface.php | 105 -- .../psr/cache/src/CacheItemPoolInterface.php | 138 -- .../cache/src/InvalidArgumentException.php | 13 - vendor/services.php | 2 +- vendor/symfony/polyfill-mbstring/Mbstring.php | 61 +- .../symfony/polyfill-mbstring/composer.json | 2 +- vendor/symfony/polyfill-php72/Php72.php | 6 +- vendor/symfony/polyfill-php72/composer.json | 2 +- .../Resources/stubs/Attribute.php | 9 + .../Resources/stubs/PhpToken.php | 11 +- .../Resources/stubs/Stringable.php | 9 + .../Resources/stubs/UnhandledMatchError.php | 9 + .../Resources/stubs/ValueError.php | 9 + vendor/symfony/polyfill-php80/composer.json | 2 +- .../var-dumper/Resources/bin/var-dump-server | 4 + vendor/topthink/framework/README.md | 7 +- vendor/topthink/framework/composer.json | 2 - vendor/topthink/framework/src/think/App.php | 3 +- .../topthink/framework/src/think/Console.php | 7 +- .../framework/src/think/Filesystem.php | 89 -- vendor/topthink/framework/src/think/Lang.php | 54 - .../framework/src/think/facade/Filesystem.php | 33 - .../src/think/filesystem/CacheStore.php | 54 - .../framework/src/think/filesystem/Driver.php | 144 -- .../src/think/filesystem/driver/Local.php | 59 - .../src/think/middleware/LoadLangPack.php | 28 +- .../framework/tests/FilesystemTest.php | 131 -- vendor/topthink/think-multi-app/composer.json | 2 +- vendor/topthink/think-multi-app/src/Url.php | 10 +- vendor/topthink/think-trace/composer.json | 2 +- 279 files changed, 4322 insertions(+), 15159 deletions(-) create mode 100644 vendor/ezyang/htmlpurifier/CHANGELOG.md create mode 100644 vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php delete mode 100644 vendor/league/flysystem-cached-adapter/.editorconfig delete mode 100644 vendor/league/flysystem-cached-adapter/.gitignore delete mode 100644 vendor/league/flysystem-cached-adapter/.php_cs delete mode 100644 vendor/league/flysystem-cached-adapter/.scrutinizer.yml delete mode 100644 vendor/league/flysystem-cached-adapter/.travis.yml delete mode 100644 vendor/league/flysystem-cached-adapter/LICENSE delete mode 100644 vendor/league/flysystem-cached-adapter/clover/.gitignore delete mode 100644 vendor/league/flysystem-cached-adapter/composer.json delete mode 100644 vendor/league/flysystem-cached-adapter/phpspec.yml delete mode 100644 vendor/league/flysystem-cached-adapter/phpunit.php delete mode 100644 vendor/league/flysystem-cached-adapter/phpunit.xml delete mode 100644 vendor/league/flysystem-cached-adapter/readme.md delete mode 100644 vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/CacheInterface.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/CachedAdapter.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Memory.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Noop.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/PhpRedis.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Predis.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php delete mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Stash.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/InspectionTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/PredisTests.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php delete mode 100644 vendor/league/flysystem-cached-adapter/tests/StashTest.php delete mode 100644 vendor/league/flysystem/CODE_OF_CONDUCT.md delete mode 100644 vendor/league/flysystem/LICENSE delete mode 100644 vendor/league/flysystem/SECURITY.md delete mode 100644 vendor/league/flysystem/composer.json delete mode 100644 vendor/league/flysystem/deprecations.md delete mode 100644 vendor/league/flysystem/src/Adapter/AbstractAdapter.php delete mode 100644 vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php delete mode 100644 vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php delete mode 100644 vendor/league/flysystem/src/Adapter/Ftp.php delete mode 100644 vendor/league/flysystem/src/Adapter/Ftpd.php delete mode 100644 vendor/league/flysystem/src/Adapter/Local.php delete mode 100644 vendor/league/flysystem/src/Adapter/NullAdapter.php delete mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php delete mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedCopyTrait.php delete mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php delete mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php delete mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php delete mode 100644 vendor/league/flysystem/src/Adapter/SynologyFtp.php delete mode 100644 vendor/league/flysystem/src/AdapterInterface.php delete mode 100644 vendor/league/flysystem/src/Config.php delete mode 100644 vendor/league/flysystem/src/ConfigAwareTrait.php delete mode 100644 vendor/league/flysystem/src/ConnectionErrorException.php delete mode 100644 vendor/league/flysystem/src/ConnectionRuntimeException.php delete mode 100644 vendor/league/flysystem/src/CorruptedPathDetected.php delete mode 100644 vendor/league/flysystem/src/Directory.php delete mode 100644 vendor/league/flysystem/src/Exception.php delete mode 100644 vendor/league/flysystem/src/File.php delete mode 100644 vendor/league/flysystem/src/FileExistsException.php delete mode 100644 vendor/league/flysystem/src/FileNotFoundException.php delete mode 100644 vendor/league/flysystem/src/Filesystem.php delete mode 100644 vendor/league/flysystem/src/FilesystemException.php delete mode 100644 vendor/league/flysystem/src/FilesystemInterface.php delete mode 100644 vendor/league/flysystem/src/FilesystemNotFoundException.php delete mode 100644 vendor/league/flysystem/src/Handler.php delete mode 100644 vendor/league/flysystem/src/InvalidRootException.php delete mode 100644 vendor/league/flysystem/src/MountManager.php delete mode 100644 vendor/league/flysystem/src/NotSupportedException.php delete mode 100644 vendor/league/flysystem/src/Plugin/AbstractPlugin.php delete mode 100644 vendor/league/flysystem/src/Plugin/EmptyDir.php delete mode 100644 vendor/league/flysystem/src/Plugin/ForcedCopy.php delete mode 100644 vendor/league/flysystem/src/Plugin/ForcedRename.php delete mode 100644 vendor/league/flysystem/src/Plugin/GetWithMetadata.php delete mode 100644 vendor/league/flysystem/src/Plugin/ListFiles.php delete mode 100644 vendor/league/flysystem/src/Plugin/ListPaths.php delete mode 100644 vendor/league/flysystem/src/Plugin/ListWith.php delete mode 100644 vendor/league/flysystem/src/Plugin/PluggableTrait.php delete mode 100644 vendor/league/flysystem/src/Plugin/PluginNotFoundException.php delete mode 100644 vendor/league/flysystem/src/PluginInterface.php delete mode 100644 vendor/league/flysystem/src/ReadInterface.php delete mode 100644 vendor/league/flysystem/src/RootViolationException.php delete mode 100644 vendor/league/flysystem/src/SafeStorage.php delete mode 100644 vendor/league/flysystem/src/UnreadableFileException.php delete mode 100644 vendor/league/flysystem/src/Util.php delete mode 100644 vendor/league/flysystem/src/Util/ContentListingFormatter.php delete mode 100644 vendor/league/flysystem/src/Util/MimeType.php delete mode 100644 vendor/league/flysystem/src/Util/StreamHasher.php delete mode 100644 vendor/league/mime-type-detection/CHANGELOG.md delete mode 100644 vendor/league/mime-type-detection/LICENSE delete mode 100644 vendor/league/mime-type-detection/composer.json delete mode 100644 vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php delete mode 100644 vendor/league/mime-type-detection/src/ExtensionMimeTypeDetector.php delete mode 100644 vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php delete mode 100644 vendor/league/mime-type-detection/src/FinfoMimeTypeDetector.php delete mode 100644 vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php delete mode 100644 vendor/league/mime-type-detection/src/MimeTypeDetector.php delete mode 100644 vendor/league/mime-type-detection/src/OverridingExtensionToMimeTypeMap.php create mode 100644 vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php create mode 100644 vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/MtJpGraphRenderer.php create mode 100644 vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/TrendLine.php rename vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/{Memory.php => Memory/SimpleCache1.php} (93%) create mode 100644 vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory/SimpleCache3.php create mode 100644 vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php delete mode 100644 vendor/psr/cache/CHANGELOG.md delete mode 100644 vendor/psr/cache/LICENSE.txt delete mode 100644 vendor/psr/cache/README.md delete mode 100644 vendor/psr/cache/composer.json delete mode 100644 vendor/psr/cache/src/CacheException.php delete mode 100644 vendor/psr/cache/src/CacheItemInterface.php delete mode 100644 vendor/psr/cache/src/CacheItemPoolInterface.php delete mode 100644 vendor/psr/cache/src/InvalidArgumentException.php delete mode 100644 vendor/topthink/framework/src/think/Filesystem.php delete mode 100644 vendor/topthink/framework/src/think/facade/Filesystem.php delete mode 100644 vendor/topthink/framework/src/think/filesystem/CacheStore.php delete mode 100644 vendor/topthink/framework/src/think/filesystem/Driver.php delete mode 100644 vendor/topthink/framework/src/think/filesystem/driver/Local.php delete mode 100644 vendor/topthink/framework/tests/FilesystemTest.php diff --git a/app/common.php b/app/common.php index 8a926f0f3..ef0751873 100755 --- a/app/common.php +++ b/app/common.php @@ -1874,7 +1874,8 @@ function MyUrl($path, $params = []) $ds = ($script_name == 'index.php') ? '/' : ''; $join = ($script_name != 'index.php' || $url_model == 0) ? $ds.'?s=' : '/'; $len = $is_api ? 4 : ($is_install ? 8 : 6); - $url = str_replace('/'.$path, $join.substr($path, $len), $url); + $path = substr($path, $len); + $url = str_replace('/'.$path, $join.$path, $url); // 避免非当前目录生成url索引错误 if($script_name != 'index.php' && $is_index) diff --git a/composer.lock b/composer.lock index e69df4c2b..f74d9f54c 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "ezyang/htmlpurifier", - "version": "v4.14.0", + "version": "v4.16.0", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75" + "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75", - "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8", + "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8", "shasum": "", "mirrors": [ { @@ -27,7 +27,17 @@ ] }, "require": { - "php": ">=5.2" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" }, "type": "library", "autoload": { @@ -59,228 +69,9 @@ ], "support": { "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0" + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0" }, - "time": "2021-12-25T01:21:49+00:00" - }, - { - "name": "league/flysystem", - "version": "1.1.9", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-fileinfo": "*", - "league/mime-type-detection": "^1.3", - "php": "^7.2.5 || ^8.0" - }, - "conflict": { - "league/flysystem-sftp": "<1.0.6" - }, - "require-dev": { - "phpspec/prophecy": "^1.11.1", - "phpunit/phpunit": "^8.5.8" - }, - "suggest": { - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "description": "Filesystem abstraction: Many filesystems, one API.", - "keywords": [ - "Cloud Files", - "WebDAV", - "abstraction", - "aws", - "cloud", - "copy.com", - "dropbox", - "file systems", - "files", - "filesystem", - "filesystems", - "ftp", - "rackspace", - "remote", - "s3", - "sftp", - "storage" - ], - "support": { - "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.9" - }, - "funding": [ - { - "url": "https://offset.earth/frankdejonge", - "type": "other" - } - ], - "time": "2021-12-09T09:40:50+00:00" - }, - { - "name": "league/flysystem-cached-adapter", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-cached-adapter.git", - "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff", - "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "league/flysystem": "~1.0", - "psr/cache": "^1.0.0" - }, - "require-dev": { - "mockery/mockery": "~0.9", - "phpspec/phpspec": "^3.4", - "phpunit/phpunit": "^5.7", - "predis/predis": "~1.0", - "tedivm/stash": "~0.12" - }, - "suggest": { - "ext-phpredis": "Pure C implemented extension for PHP" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\Cached\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "frankdejonge", - "email": "info@frenky.net" - } - ], - "description": "An adapter decorator to enable meta-data caching.", - "support": { - "issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues", - "source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master" - }, - "time": "2020-07-25T15:56:04+00:00" - }, - { - "name": "league/mime-type-detection", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Mime-type detection for Flysystem", - "support": { - "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" - }, - "funding": [ - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "time": "2022-04-17T13:12:02+00:00" + "time": "2022-09-18T07:06:19+00:00" }, { "name": "maennchen/zipstream-php", @@ -627,16 +418,16 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "1.24.0", + "version": "1.25.2", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "ebe8745c92a7cac4514d040758393b5399633b83" + "reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ebe8745c92a7cac4514d040758393b5399633b83", - "reference": "ebe8745c92a7cac4514d040758393b5399633b83", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a317a09e7def49852400a4b3eca4a4b0790ceeb5", + "reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5", "shasum": "", "mirrors": [ { @@ -659,33 +450,34 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.13", + "ezyang/htmlpurifier": "^4.15", "maennchen/zipstream-php": "^2.1", "markbaker/complex": "^3.0", "markbaker/matrix": "^3.0", "php": "^7.3 || ^8.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/simple-cache": "^1.0 || ^2.0" + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-master", "dompdf/dompdf": "^1.0 || ^2.0", "friendsofphp/php-cs-fixer": "^3.2", - "jpgraph/jpgraph": "^4.0", + "mitoteam/jpgraph": "10.2.4", "mpdf/mpdf": "8.1.1", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.7", - "tecnickcom/tcpdf": "^6.4" + "tecnickcom/tcpdf": "6.5" }, "suggest": { - "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", - "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions", + "mitoteam/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 (doesn't yet support PHP8)" + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" }, "type": "library", "autoload": { @@ -731,64 +523,9 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.24.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.25.2" }, - "time": "2022-07-09T13:49:09+00:00" - }, - { - "name": "psr/cache", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/master" - }, - "time": "2016-08-06T20:24:11+00:00" + "time": "2022-09-25T17:21:01+00:00" }, { "name": "psr/container", @@ -1137,16 +874,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "", "mirrors": [ { @@ -1167,7 +904,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1206,7 +943,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -1222,20 +959,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "topthink/framework", - "version": "v6.0.13", + "version": "v6.1.1", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6" + "reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6", - "reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6", + "url": "https://api.github.com/repos/top-think/framework/zipball/2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210", + "reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210", "shasum": "", "mirrors": [ { @@ -1247,8 +984,6 @@ "require": { "ext-json": "*", "ext-mbstring": "*", - "league/flysystem": "^1.1.4", - "league/flysystem-cached-adapter": "^1.0", "php": ">=7.2.5", "psr/container": "~1.0", "psr/http-message": "^1.0", @@ -1293,9 +1028,9 @@ ], "support": { "issues": "https://github.com/top-think/framework/issues", - "source": "https://github.com/top-think/framework/tree/v6.0.13" + "source": "https://github.com/top-think/framework/tree/v6.1.1" }, - "time": "2022-07-15T02:52:08+00:00" + "time": "2022-10-26T03:48:53+00:00" }, { "name": "topthink/think-helper", @@ -1351,16 +1086,16 @@ }, { "name": "topthink/think-multi-app", - "version": "v1.0.14", + "version": "v1.0.15", "source": { "type": "git", "url": "https://github.com/top-think/think-multi-app.git", - "reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3" + "reference": "387e0dac059c20f92cac5da41a871e10829c1c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3", - "reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3", + "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/387e0dac059c20f92cac5da41a871e10829c1c97", + "reference": "387e0dac059c20f92cac5da41a871e10829c1c97", "shasum": "", "mirrors": [ { @@ -1371,7 +1106,7 @@ }, "require": { "php": ">=7.1.0", - "topthink/framework": "^6.0.0" + "topthink/framework": "^6.0" }, "type": "library", "extra": { @@ -1399,9 +1134,9 @@ "description": "thinkphp6 multi app support", "support": { "issues": "https://github.com/top-think/think-multi-app/issues", - "source": "https://github.com/top-think/think-multi-app/tree/master" + "source": "https://github.com/top-think/think-multi-app/tree/v1.0.15" }, - "time": "2020-07-12T13:50:37+00:00" + "time": "2022-10-26T08:03:06+00:00" }, { "name": "topthink/think-orm", @@ -1562,16 +1297,16 @@ "packages-dev": [ { "name": "symfony/polyfill-php72", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", "shasum": "", "mirrors": [ { @@ -1586,7 +1321,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1624,7 +1359,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" }, "funding": [ { @@ -1640,20 +1375,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "", "mirrors": [ { @@ -1668,7 +1403,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1713,7 +1448,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -1729,20 +1464,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.4.44", + "version": "v4.4.47", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed" + "reference": "1069c7a3fca74578022fab6f81643248d02f8e63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63", + "reference": "1069c7a3fca74578022fab6f81643248d02f8e63", "shasum": "", "mirrors": [ { @@ -1808,7 +1543,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.44" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.47" }, "funding": [ { @@ -1824,20 +1559,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T09:59:04+00:00" + "time": "2022-10-03T15:15:11+00:00" }, { "name": "topthink/think-trace", - "version": "v1.4", + "version": "v1.5", "source": { "type": "git", "url": "https://github.com/top-think/think-trace.git", - "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444" + "reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444", - "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444", + "url": "https://api.github.com/repos/top-think/think-trace/zipball/55027fd79abb744f32a3be8d9e1ccf873a3ca9b7", + "reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7", "shasum": "", "mirrors": [ { @@ -1848,7 +1583,7 @@ }, "require": { "php": ">=7.1.0", - "topthink/framework": "^6.0.0" + "topthink/framework": "^6.0" }, "type": "library", "extra": { @@ -1879,9 +1614,9 @@ "description": "thinkphp debug trace", "support": { "issues": "https://github.com/top-think/think-trace/issues", - "source": "https://github.com/top-think/think-trace/tree/v1.4" + "source": "https://github.com/top-think/think-trace/tree/v1.5" }, - "time": "2020-06-29T05:27:28+00:00" + "time": "2022-10-26T07:56:45+00:00" } ], "aliases": [], diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 90ff71461..a8231bc6f 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -7,11 +7,11 @@ $baseDir = dirname($vendorDir); return array( '9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php', - '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', - '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', + '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', + '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', 'dc1275c308c5b416beb314b6317daca2' => $vendorDir . '/overtrue/pinyin/src/const.php', + '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 55c471c88..515c5baaa 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -9,7 +9,7 @@ return array( 'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'), 'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'), 'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'), - 'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'), + 'think\\' => array($vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/framework/src/think'), 'app\\' => array($baseDir . '/app'), 'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), @@ -21,13 +21,9 @@ return array( 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), - 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'), 'Overtrue\\Pinyin\\' => array($vendorDir . '/overtrue/pinyin/src'), 'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'), 'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'), - 'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'), - 'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'), - 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), 'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'), ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index c0164b79d..4fdef920f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -8,13 +8,13 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1 { public static $files = array ( '9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php', - '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', - '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', + '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', + '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', 'dc1275c308c5b416beb314b6317daca2' => __DIR__ . '/..' . '/overtrue/pinyin/src/const.php', + '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', ); public static $prefixLengthsPsr4 = array ( @@ -47,7 +47,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1 'Psr\\Http\\Message\\' => 17, 'Psr\\Http\\Client\\' => 16, 'Psr\\Container\\' => 14, - 'Psr\\Cache\\' => 10, 'PhpOffice\\PhpSpreadsheet\\' => 25, ), 'O' => @@ -59,12 +58,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1 'MyCLabs\\Enum\\' => 13, 'Matrix\\' => 7, ), - 'L' => - array ( - 'League\\MimeTypeDetection\\' => 25, - 'League\\Flysystem\\Cached\\' => 24, - 'League\\Flysystem\\' => 17, - ), 'C' => array ( 'Complex\\' => 8, @@ -86,10 +79,10 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1 ), 'think\\' => array ( - 0 => __DIR__ . '/..' . '/topthink/framework/src/think', - 1 => __DIR__ . '/..' . '/topthink/think-helper/src', - 2 => __DIR__ . '/..' . '/topthink/think-orm/src', - 3 => __DIR__ . '/..' . '/topthink/think-template/src', + 0 => __DIR__ . '/..' . '/topthink/think-helper/src', + 1 => __DIR__ . '/..' . '/topthink/think-orm/src', + 2 => __DIR__ . '/..' . '/topthink/think-template/src', + 3 => __DIR__ . '/..' . '/topthink/framework/src/think', ), 'app\\' => array ( @@ -136,10 +129,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1 array ( 0 => __DIR__ . '/..' . '/psr/container/src', ), - 'Psr\\Cache\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/cache/src', - ), 'PhpOffice\\PhpSpreadsheet\\' => array ( 0 => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet', @@ -156,18 +145,6 @@ class ComposerStaticInit1ed187777399b73a018d9a6af63a57d1 array ( 0 => __DIR__ . '/..' . '/markbaker/matrix/classes/src', ), - 'League\\MimeTypeDetection\\' => - array ( - 0 => __DIR__ . '/..' . '/league/mime-type-detection/src', - ), - 'League\\Flysystem\\Cached\\' => - array ( - 0 => __DIR__ . '/..' . '/league/flysystem-cached-adapter/src', - ), - 'League\\Flysystem\\' => - array ( - 0 => __DIR__ . '/..' . '/league/flysystem/src', - ), 'Complex\\' => array ( 0 => __DIR__ . '/..' . '/markbaker/complex/classes/src', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 793c043dd..753e73530 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "ezyang/htmlpurifier", - "version": "v4.14.0", - "version_normalized": "4.14.0.0", + "version": "v4.16.0", + "version_normalized": "4.16.0.0", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75" + "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75", - "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8", + "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8", "shasum": "", "mirrors": [ { @@ -22,18 +22,28 @@ ] }, "require": { - "php": ">=5.2" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" }, - "time": "2021-12-25T01:21:49+00:00", + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "time": "2022-09-18T07:06:19+00:00", "type": "library", "installation-source": "dist", "autoload": { - "psr-0": { - "HTMLPurifier": "library/" - }, "files": [ "library/HTMLPurifier.composer.php" ], + "psr-0": { + "HTMLPurifier": "library/" + }, "exclude-from-classmap": [ "/library/HTMLPurifier/Language/" ] @@ -56,232 +66,10 @@ ], "support": { "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0" + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0" }, "install-path": "../ezyang/htmlpurifier" }, - { - "name": "league/flysystem", - "version": "1.1.9", - "version_normalized": "1.1.9.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99", - "reference": "094defdb4a7001845300334e7c1ee2335925ef99", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-fileinfo": "*", - "league/mime-type-detection": "^1.3", - "php": "^7.2.5 || ^8.0" - }, - "conflict": { - "league/flysystem-sftp": "<1.0.6" - }, - "require-dev": { - "phpspec/prophecy": "^1.11.1", - "phpunit/phpunit": "^8.5.8" - }, - "suggest": { - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" - }, - "time": "2021-12-09T09:40:50+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "description": "Filesystem abstraction: Many filesystems, one API.", - "keywords": [ - "Cloud Files", - "WebDAV", - "abstraction", - "aws", - "cloud", - "copy.com", - "dropbox", - "file systems", - "files", - "filesystem", - "filesystems", - "ftp", - "rackspace", - "remote", - "s3", - "sftp", - "storage" - ], - "support": { - "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.9" - }, - "funding": [ - { - "url": "https://offset.earth/frankdejonge", - "type": "other" - } - ], - "install-path": "../league/flysystem" - }, - { - "name": "league/flysystem-cached-adapter", - "version": "1.1.0", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-cached-adapter.git", - "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff", - "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff", - "shasum": "" - }, - "require": { - "league/flysystem": "~1.0", - "psr/cache": "^1.0.0" - }, - "require-dev": { - "mockery/mockery": "~0.9", - "phpspec/phpspec": "^3.4", - "phpunit/phpunit": "^5.7", - "predis/predis": "~1.0", - "tedivm/stash": "~0.12" - }, - "suggest": { - "ext-phpredis": "Pure C implemented extension for PHP" - }, - "time": "2020-07-25T15:56:04+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "League\\Flysystem\\Cached\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "frankdejonge", - "email": "info@frenky.net" - } - ], - "description": "An adapter decorator to enable meta-data caching.", - "support": { - "issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues", - "source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master" - }, - "install-path": "../league/flysystem-cached-adapter" - }, - { - "name": "league/mime-type-detection", - "version": "1.11.0", - "version_normalized": "1.11.0.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" - }, - "time": "2022-04-17T13:12:02+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Mime-type detection for Flysystem", - "support": { - "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" - }, - "funding": [ - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "install-path": "../league/mime-type-detection" - }, { "name": "maennchen/zipstream-php", "version": "2.2.1", @@ -642,17 +430,17 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "1.24.0", - "version_normalized": "1.24.0.0", + "version": "1.25.2", + "version_normalized": "1.25.2.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "ebe8745c92a7cac4514d040758393b5399633b83" + "reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ebe8745c92a7cac4514d040758393b5399633b83", - "reference": "ebe8745c92a7cac4514d040758393b5399633b83", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a317a09e7def49852400a4b3eca4a4b0790ceeb5", + "reference": "a317a09e7def49852400a4b3eca4a4b0790ceeb5", "shasum": "", "mirrors": [ { @@ -675,35 +463,36 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.13", + "ezyang/htmlpurifier": "^4.15", "maennchen/zipstream-php": "^2.1", "markbaker/complex": "^3.0", "markbaker/matrix": "^3.0", "php": "^7.3 || ^8.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/simple-cache": "^1.0 || ^2.0" + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-master", "dompdf/dompdf": "^1.0 || ^2.0", "friendsofphp/php-cs-fixer": "^3.2", - "jpgraph/jpgraph": "^4.0", + "mitoteam/jpgraph": "10.2.4", "mpdf/mpdf": "8.1.1", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.7", - "tecnickcom/tcpdf": "^6.4" + "tecnickcom/tcpdf": "6.5" }, "suggest": { - "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", - "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions", + "mitoteam/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 (doesn't yet support PHP8)" + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" }, - "time": "2022-07-09T13:49:09+00:00", + "time": "2022-09-25T17:21:01+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -749,62 +538,10 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.24.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.25.2" }, "install-path": "../phpoffice/phpspreadsheet" }, - { - "name": "psr/cache", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2016-08-06T20:24:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/master" - }, - "install-path": "../psr/cache" - }, { "name": "psr/container", "version": "1.1.2", @@ -1158,17 +895,17 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", - "version_normalized": "1.26.0.0", + "version": "v1.27.0", + "version_normalized": "1.27.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "", "mirrors": [ { @@ -1186,11 +923,11 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2022-05-24T11:49:31+00:00", + "time": "2022-11-03T14:55:06+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1230,7 +967,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -1250,17 +987,17 @@ }, { "name": "symfony/polyfill-php72", - "version": "v1.26.0", - "version_normalized": "1.26.0.0", + "version": "v1.27.0", + "version_normalized": "1.27.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", "shasum": "", "mirrors": [ { @@ -1272,11 +1009,11 @@ "require": { "php": ">=7.1" }, - "time": "2022-05-24T11:49:31+00:00", + "time": "2022-11-03T14:55:06+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1315,7 +1052,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" }, "funding": [ { @@ -1335,17 +1072,17 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", - "version_normalized": "1.26.0.0", + "version": "v1.27.0", + "version_normalized": "1.27.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "", "mirrors": [ { @@ -1357,11 +1094,11 @@ "require": { "php": ">=7.1" }, - "time": "2022-05-10T07:21:04+00:00", + "time": "2022-11-03T14:55:06+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1407,7 +1144,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -1427,17 +1164,17 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.44", - "version_normalized": "4.4.44.0", + "version": "v4.4.47", + "version_normalized": "4.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed" + "reference": "1069c7a3fca74578022fab6f81643248d02f8e63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f19951007dae942cc79b979c1fe26bfdfbeb54ed", - "reference": "f19951007dae942cc79b979c1fe26bfdfbeb54ed", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63", + "reference": "1069c7a3fca74578022fab6f81643248d02f8e63", "shasum": "", "mirrors": [ { @@ -1467,7 +1204,7 @@ "ext-intl": "To show region name in time zone dump", "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" }, - "time": "2022-07-20T09:59:04+00:00", + "time": "2022-10-03T15:15:11+00:00", "bin": [ "Resources/bin/var-dump-server" ], @@ -1505,7 +1242,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.44" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.47" }, "funding": [ { @@ -1525,17 +1262,17 @@ }, { "name": "topthink/framework", - "version": "v6.0.13", - "version_normalized": "6.0.13.0", + "version": "v6.1.1", + "version_normalized": "6.1.1.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6" + "reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6", - "reference": "126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6", + "url": "https://api.github.com/repos/top-think/framework/zipball/2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210", + "reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210", "shasum": "", "mirrors": [ { @@ -1547,8 +1284,6 @@ "require": { "ext-json": "*", "ext-mbstring": "*", - "league/flysystem": "^1.1.4", - "league/flysystem-cached-adapter": "^1.0", "php": ">=7.2.5", "psr/container": "~1.0", "psr/http-message": "^1.0", @@ -1563,7 +1298,7 @@ "mockery/mockery": "^1.2", "phpunit/phpunit": "^7.0" }, - "time": "2022-07-15T02:52:08+00:00", + "time": "2022-10-26T03:48:53+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1595,7 +1330,7 @@ ], "support": { "issues": "https://github.com/top-think/framework/issues", - "source": "https://github.com/top-think/framework/tree/v6.0.13" + "source": "https://github.com/top-think/framework/tree/v6.1.1" }, "install-path": "../topthink/framework" }, @@ -1656,24 +1391,30 @@ }, { "name": "topthink/think-multi-app", - "version": "v1.0.14", - "version_normalized": "1.0.14.0", + "version": "v1.0.15", + "version_normalized": "1.0.15.0", "source": { "type": "git", "url": "https://github.com/top-think/think-multi-app.git", - "reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3" + "reference": "387e0dac059c20f92cac5da41a871e10829c1c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3", - "reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3", - "shasum": "" + "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/387e0dac059c20f92cac5da41a871e10829c1c97", + "reference": "387e0dac059c20f92cac5da41a871e10829c1c97", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1.0", - "topthink/framework": "^6.0.0" + "topthink/framework": "^6.0" }, - "time": "2020-07-12T13:50:37+00:00", + "time": "2022-10-26T08:03:06+00:00", "type": "library", "extra": { "think": { @@ -1701,7 +1442,7 @@ "description": "thinkphp6 multi app support", "support": { "issues": "https://github.com/top-think/think-multi-app/issues", - "source": "https://github.com/top-think/think-multi-app/tree/master" + "source": "https://github.com/top-think/think-multi-app/tree/v1.0.15" }, "install-path": "../topthink/think-multi-app" }, @@ -1815,24 +1556,30 @@ }, { "name": "topthink/think-trace", - "version": "v1.4", - "version_normalized": "1.4.0.0", + "version": "v1.5", + "version_normalized": "1.5.0.0", "source": { "type": "git", "url": "https://github.com/top-think/think-trace.git", - "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444" + "reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444", - "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444", - "shasum": "" + "url": "https://api.github.com/repos/top-think/think-trace/zipball/55027fd79abb744f32a3be8d9e1ccf873a3ca9b7", + "reference": "55027fd79abb744f32a3be8d9e1ccf873a3ca9b7", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1.0", - "topthink/framework": "^6.0.0" + "topthink/framework": "^6.0" }, - "time": "2020-06-29T05:27:28+00:00", + "time": "2022-10-26T07:56:45+00:00", "type": "library", "extra": { "think": { @@ -1863,7 +1610,7 @@ "description": "thinkphp debug trace", "support": { "issues": "https://github.com/top-think/think-trace/issues", - "source": "https://github.com/top-think/think-trace/tree/v1.4" + "source": "https://github.com/top-think/think-trace/tree/v1.5" }, "install-path": "../topthink/think-trace" }, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 13da4c8ef..405ed8722 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -5,45 +5,18 @@ 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '2a77126a1909be677e6bde7c623bb5a0fb75d32b', + 'reference' => 'ec0420fb511804f40321aab88a9025e147cf54f4', 'name' => 'shopxo/shopxo', 'dev' => true, ), 'versions' => array( 'ezyang/htmlpurifier' => array( - 'pretty_version' => 'v4.14.0', - 'version' => '4.14.0.0', + 'pretty_version' => 'v4.16.0', + 'version' => '4.16.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../ezyang/htmlpurifier', 'aliases' => array(), - 'reference' => '12ab42bd6e742c70c0a52f7b82477fcd44e64b75', - 'dev_requirement' => false, - ), - 'league/flysystem' => array( - 'pretty_version' => '1.1.9', - 'version' => '1.1.9.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../league/flysystem', - 'aliases' => array(), - 'reference' => '094defdb4a7001845300334e7c1ee2335925ef99', - 'dev_requirement' => false, - ), - 'league/flysystem-cached-adapter' => array( - 'pretty_version' => '1.1.0', - 'version' => '1.1.0.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../league/flysystem-cached-adapter', - 'aliases' => array(), - 'reference' => 'd1925efb2207ac4be3ad0c40b8277175f99ffaff', - 'dev_requirement' => false, - ), - 'league/mime-type-detection' => array( - 'pretty_version' => '1.11.0', - 'version' => '1.11.0.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../league/mime-type-detection', - 'aliases' => array(), - 'reference' => 'ff6248ea87a9f116e78edd6002e39e5128a0d4dd', + 'reference' => '523407fb06eb9e5f3d59889b3978d5bfe94299c8', 'dev_requirement' => false, ), 'maennchen/zipstream-php' => array( @@ -92,21 +65,12 @@ 'dev_requirement' => false, ), 'phpoffice/phpspreadsheet' => array( - 'pretty_version' => '1.24.0', - 'version' => '1.24.0.0', + 'pretty_version' => '1.25.2', + 'version' => '1.25.2.0', 'type' => 'library', 'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet', 'aliases' => array(), - 'reference' => 'ebe8745c92a7cac4514d040758393b5399633b83', - 'dev_requirement' => false, - ), - 'psr/cache' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/cache', - 'aliases' => array(), - 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'reference' => 'a317a09e7def49852400a4b3eca4a4b0790ceeb5', 'dev_requirement' => false, ), 'psr/container' => array( @@ -169,52 +133,52 @@ 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '2a77126a1909be677e6bde7c623bb5a0fb75d32b', + 'reference' => 'ec0420fb511804f40321aab88a9025e147cf54f4', 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.26.0', - 'version' => '1.26.0.0', + 'pretty_version' => 'v1.27.0', + 'version' => '1.27.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), - 'reference' => '9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e', + 'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534', 'dev_requirement' => false, ), 'symfony/polyfill-php72' => array( - 'pretty_version' => 'v1.26.0', - 'version' => '1.26.0.0', + 'pretty_version' => 'v1.27.0', + 'version' => '1.27.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php72', 'aliases' => array(), - 'reference' => 'bf44a9fd41feaac72b074de600314a93e2ae78e2', + 'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97', 'dev_requirement' => true, ), 'symfony/polyfill-php80' => array( - 'pretty_version' => 'v1.26.0', - 'version' => '1.26.0.0', + 'pretty_version' => 'v1.27.0', + 'version' => '1.27.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), - 'reference' => 'cfa0ae98841b9e461207c13ab093d76b0fa7bace', + 'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936', 'dev_requirement' => true, ), 'symfony/var-dumper' => array( - 'pretty_version' => 'v4.4.44', - 'version' => '4.4.44.0', + 'pretty_version' => 'v4.4.47', + 'version' => '4.4.47.0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/var-dumper', 'aliases' => array(), - 'reference' => 'f19951007dae942cc79b979c1fe26bfdfbeb54ed', + 'reference' => '1069c7a3fca74578022fab6f81643248d02f8e63', 'dev_requirement' => true, ), 'topthink/framework' => array( - 'pretty_version' => 'v6.0.13', - 'version' => '6.0.13.0', + 'pretty_version' => 'v6.1.1', + 'version' => '6.1.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../topthink/framework', 'aliases' => array(), - 'reference' => '126d5b2cbacb73d6e2a85cbc7a2c6ee59d0b3fa6', + 'reference' => '2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210', 'dev_requirement' => false, ), 'topthink/think-helper' => array( @@ -227,12 +191,12 @@ 'dev_requirement' => false, ), 'topthink/think-multi-app' => array( - 'pretty_version' => 'v1.0.14', - 'version' => '1.0.14.0', + 'pretty_version' => 'v1.0.15', + 'version' => '1.0.15.0', 'type' => 'library', 'install_path' => __DIR__ . '/../topthink/think-multi-app', 'aliases' => array(), - 'reference' => 'ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3', + 'reference' => '387e0dac059c20f92cac5da41a871e10829c1c97', 'dev_requirement' => false, ), 'topthink/think-orm' => array( @@ -254,12 +218,12 @@ 'dev_requirement' => false, ), 'topthink/think-trace' => array( - 'pretty_version' => 'v1.4', - 'version' => '1.4.0.0', + 'pretty_version' => 'v1.5', + 'version' => '1.5.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../topthink/think-trace', 'aliases' => array(), - 'reference' => '9a9fa8f767b6c66c5a133ad21ca1bc96ad329444', + 'reference' => '55027fd79abb744f32a3be8d9e1ccf873a3ca9b7', 'dev_requirement' => true, ), 'topthink/think-view' => array( diff --git a/vendor/ezyang/htmlpurifier/CHANGELOG.md b/vendor/ezyang/htmlpurifier/CHANGELOG.md new file mode 100644 index 000000000..55cb9029c --- /dev/null +++ b/vendor/ezyang/htmlpurifier/CHANGELOG.md @@ -0,0 +1,6 @@ +# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18) + + +### Features + +* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338) diff --git a/vendor/ezyang/htmlpurifier/VERSION b/vendor/ezyang/htmlpurifier/VERSION index 09ce0ce71..f029ee574 100644 --- a/vendor/ezyang/htmlpurifier/VERSION +++ b/vendor/ezyang/htmlpurifier/VERSION @@ -1 +1 @@ -4.14.0 \ No newline at end of file +4.15.0 \ No newline at end of file diff --git a/vendor/ezyang/htmlpurifier/composer.json b/vendor/ezyang/htmlpurifier/composer.json index 5f62d889d..d75582950 100644 --- a/vendor/ezyang/htmlpurifier/composer.json +++ b/vendor/ezyang/htmlpurifier/composer.json @@ -13,7 +13,11 @@ } ], "require": { - "php": ">=5.2" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" }, "autoload": { "psr-0": { "HTMLPurifier": "library/" }, @@ -21,5 +25,20 @@ "exclude-from-classmap": [ "/library/HTMLPurifier/Language/" ] - } + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-tidy": "Used for pretty-printing HTML" + }, + "config": { + "sort-packages": true + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/ezyang/simpletest.git" + } + ] } diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php index ee81cac68..47ee0133d 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php @@ -7,7 +7,7 @@ * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * - * @version 4.14.0 + * @version 4.15.0 * * @warning * You must *not* include any other HTML Purifier files before this file, @@ -107,6 +107,7 @@ require 'HTMLPurifier/AttrDef/HTML/Bool.php'; require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php'; require 'HTMLPurifier/AttrDef/HTML/Class.php'; require 'HTMLPurifier/AttrDef/HTML/Color.php'; +require 'HTMLPurifier/AttrDef/HTML/ContentEditable.php'; require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php'; require 'HTMLPurifier/AttrDef/HTML/ID.php'; require 'HTMLPurifier/AttrDef/HTML/Pixels.php'; diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php index 2177fc851..26f061276 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.14.0 - Standards Compliant HTML Filtering + HTML Purifier 4.15.0 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or @@ -58,12 +58,12 @@ class HTMLPurifier * Version of HTML Purifier. * @type string */ - public $version = '4.14.0'; + public $version = '4.15.0'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.14.0'; + const VERSION = '4.15.0'; /** * Global configuration object. diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.safe-includes.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.safe-includes.php index a3261f8a3..94543f593 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.safe-includes.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.safe-includes.php @@ -101,6 +101,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php'; +require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ContentEditable.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php'; diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php new file mode 100644 index 000000000..5b03d3e37 --- /dev/null +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php @@ -0,0 +1,16 @@ +get('HTML.Trusted')) { + $allowed = array('', 'true', 'false'); + } + + $enum = new HTMLPurifier_AttrDef_Enum($allowed); + + return $enum->validate($string, $config, $context); + } +} diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php index 36079b786..5a1fdbbfc 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/NameSync.php @@ -8,6 +8,11 @@ class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform { + /** + * @type HTMLPurifier_AttrDef_HTML_ID + */ + public $idDef; + public function __construct() { $this->idDef = new HTMLPurifier_AttrDef_HTML_ID(); diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php index 1143b4b49..1033106b3 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform/SafeParam.php @@ -24,6 +24,11 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform */ private $uri; + /** + * @type HTMLPurifier_AttrDef_Enum + */ + public $wmode; + public function __construct() { $this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTypes.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTypes.php index 3b70520b6..e4429e86d 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTypes.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTypes.php @@ -41,6 +41,7 @@ class HTMLPurifier_AttrTypes $this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right'); $this->info['LAlign'] = self::makeEnum('top,bottom,left,right'); $this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget(); + $this->info['ContentEditable'] = new HTMLPurifier_AttrDef_HTML_ContentEditable(); // unimplemented aliases $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php index 4fc70e0ef..3d584e727 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php @@ -22,6 +22,8 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef // XXX: This whole business with 'wrap' is all a bit unsatisfactory public $elements = array('li' => true, 'ul' => true, 'ol' => true); + public $whitespace; + /** * @param array $children * @param HTMLPurifier_Config $config diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php index 16a6b322b..797d26877 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.14.0'; + public $version = '4.15.0'; /** * Whether or not to automatically finalize diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ElementDef.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ElementDef.php index d5311cedc..57cfd2bb0 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ElementDef.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ElementDef.php @@ -176,7 +176,7 @@ class HTMLPurifier_ElementDef if (!empty($def->content_model)) { $this->content_model = - str_replace("#SUPER", $this->content_model, $def->content_model); + str_replace("#SUPER", (string)$this->content_model, $def->content_model); $this->child = false; } if (!empty($def->content_model_type)) { diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Encoder.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Encoder.php index 40a24266a..d4791cc1b 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Encoder.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Encoder.php @@ -398,8 +398,8 @@ class HTMLPurifier_Encoder // characters to their true byte-wise ASCII/UTF-8 equivalents. $str = strtr($str, self::testEncodingSupportsASCII($encoding)); return $str; - } elseif ($encoding === 'iso-8859-1') { - $str = utf8_encode($str); + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); return $str; } $bug = HTMLPurifier_Encoder::testIconvTruncateBug(); @@ -450,8 +450,8 @@ class HTMLPurifier_Encoder // Normal stuff $str = self::iconv('utf-8', $encoding . '//IGNORE', $str); return $str; - } elseif ($encoding === 'iso-8859-1') { - $str = utf8_decode($str); + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8'); return $str; } trigger_error('Encoding not supported', E_USER_ERROR); diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/HTMLModule/CommonAttributes.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/HTMLModule/CommonAttributes.php index a96ab1bef..7220c14cc 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/HTMLModule/CommonAttributes.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/HTMLModule/CommonAttributes.php @@ -17,6 +17,7 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule 'class' => 'Class', 'id' => 'ID', 'title' => 'CDATA', + 'contenteditable' => 'ContentEditable', ), 'Lang' => array(), 'I18N' => array( diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php index 9ee7aa84d..42d514447 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php @@ -31,6 +31,16 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In */ private $context; + /** + * @type SplObjectStorage + */ + private $markForDeletion; + + public function __construct() + { + $this->markForDeletion = new SplObjectStorage(); + } + public function prepare($config, $context) { $this->attrValidator = new HTMLPurifier_AttrValidator(); @@ -64,7 +74,7 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') { // Mark closing span tag for deletion - $current->markForDeletion = true; + $this->markForDeletion->attach($current); // Delete open span tag $token = false; } @@ -75,7 +85,8 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In */ public function handleEnd(&$token) { - if ($token->markForDeletion) { + if ($this->markForDeletion->contains($token)) { + $this->markForDeletion->detach($token); $token = false; } } diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Length.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Length.php index e70da55a9..b6ea12345 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Length.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Length.php @@ -78,7 +78,7 @@ class HTMLPurifier_Length if ($this->n === '0' && $this->unit === false) { return true; } - if (!ctype_lower($this->unit)) { + if ($this->unit === false || !ctype_lower($this->unit)) { $this->unit = strtolower($this->unit); } if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) { diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php index e9da3ed5e..c21f36491 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php @@ -48,6 +48,11 @@ class HTMLPurifier_Lexer */ public $tracksLineNumbers = false; + /** + * @type HTMLPurifier_EntityParser + */ + private $_entity_parser; + // -- STATIC ---------------------------------------------------------- /** @@ -306,8 +311,8 @@ class HTMLPurifier_Lexer { // normalize newlines to \n if ($config->get('Core.NormalizeNewlines')) { - $html = str_replace("\r\n", "\n", $html); - $html = str_replace("\r", "\n", $html); + $html = str_replace("\r\n", "\n", (string)$html); + $html = str_replace("\r", "\n", (string)$html); } if ($config->get('HTML.Trusted')) { diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer/PH5P.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer/PH5P.php index 72476ddf3..1564f283d 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer/PH5P.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer/PH5P.php @@ -4410,7 +4410,7 @@ class HTML5TreeConstructer foreach ($token['attr'] as $attr) { if (!$el->hasAttribute($attr['name'])) { - $el->setAttribute($attr['name'], $attr['value']); + $el->setAttribute($attr['name'], (string)$attr['value']); } } diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/PropertyListIterator.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/PropertyListIterator.php index 15b330ea3..f68fc8c30 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/PropertyListIterator.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/PropertyListIterator.php @@ -29,6 +29,7 @@ class HTMLPurifier_PropertyListIterator extends FilterIterator /** * @return bool */ + #[\ReturnTypeWillChange] public function accept() { $key = $this->getInnerIterator()->key(); diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/StringHash.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/StringHash.php index c07370197..c41ae3a76 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/StringHash.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/StringHash.php @@ -20,6 +20,7 @@ class HTMLPurifier_StringHash extends ArrayObject * @param mixed $index * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($index) { $this->accessed[$index] = true; diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php index a6645c17e..32197c0e6 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/HostBlacklist.php @@ -35,7 +35,7 @@ class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter public function filter(&$uri, $config, $context) { foreach ($this->blacklist as $blacklisted_host_fragment) { - if (strpos($uri->host, $blacklisted_host_fragment) !== false) { + if ($uri->host !== null && strpos($uri->host, $blacklisted_host_fragment) !== false) { return false; } } diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php index 6e03315a1..e1393deb7 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/URIFilter/Munge.php @@ -100,11 +100,11 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter $string = $uri->toString(); // always available $this->replace['%s'] = $string; - $this->replace['%r'] = $context->get('EmbeddedURI', true); - $token = $context->get('CurrentToken', true); - $this->replace['%n'] = $token ? $token->name : null; - $this->replace['%m'] = $context->get('CurrentAttr', true); - $this->replace['%p'] = $context->get('CurrentCSSProperty', true); + $this->replace['%r'] = $context->get('EmbeddedURI', true) ?: ''; + $token = $context->get('CurrentToken', true) ?: ''; + $this->replace['%n'] = $token ? $token->name : ''; + $this->replace['%m'] = $context->get('CurrentAttr', true) ?: ''; + $this->replace['%p'] = $context->get('CurrentCSSProperty', true) ?: ''; // not always available if ($this->secretKey) { $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); diff --git a/vendor/league/flysystem-cached-adapter/.editorconfig b/vendor/league/flysystem-cached-adapter/.editorconfig deleted file mode 100644 index 153cf3ef5..000000000 --- a/vendor/league/flysystem-cached-adapter/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -; top-most EditorConfig file -root = true - -; Unix-style newlines -[*] -end_of_line = LF - -[*.php] -indent_style = space -indent_size = 4 diff --git a/vendor/league/flysystem-cached-adapter/.gitignore b/vendor/league/flysystem-cached-adapter/.gitignore deleted file mode 100644 index 7aea75f4f..000000000 --- a/vendor/league/flysystem-cached-adapter/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -coverage -coverage.xml -composer.lock -vendor \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/.php_cs b/vendor/league/flysystem-cached-adapter/.php_cs deleted file mode 100644 index 6643a32cf..000000000 --- a/vendor/league/flysystem-cached-adapter/.php_cs +++ /dev/null @@ -1,7 +0,0 @@ -level(Symfony\CS\FixerInterface::PSR2_LEVEL) - ->fixers(['-yoda_conditions', 'ordered_use', 'short_array_syntax']) - ->finder(Symfony\CS\Finder\DefaultFinder::create() - ->in(__DIR__.'/src/')); \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/.scrutinizer.yml b/vendor/league/flysystem-cached-adapter/.scrutinizer.yml deleted file mode 100644 index fa39b52b3..000000000 --- a/vendor/league/flysystem-cached-adapter/.scrutinizer.yml +++ /dev/null @@ -1,34 +0,0 @@ -filter: - paths: [src/*] -checks: - php: - code_rating: true - remove_extra_empty_lines: true - remove_php_closing_tag: true - remove_trailing_whitespace: true - fix_use_statements: - remove_unused: true - preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true - fix_php_opening_tag: true - fix_linefeed: true - fix_line_ending: true - fix_identation_4spaces: true - fix_doc_comments: true -tools: - external_code_coverage: - timeout: 900 - runs: 6 - php_code_coverage: false - php_code_sniffer: - config: - standard: PSR2 - filter: - paths: ['src'] - php_loc: - enabled: true - excluded_dirs: [vendor, spec, stubs] - php_cpd: - enabled: true - excluded_dirs: [vendor, spec, stubs] \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/.travis.yml b/vendor/league/flysystem-cached-adapter/.travis.yml deleted file mode 100644 index 6706449fd..000000000 --- a/vendor/league/flysystem-cached-adapter/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: php - -php: - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - -matrix: - allow_failures: - - php: 5.5 - -env: - - COMPOSER_OPTS="" - - COMPOSER_OPTS="--prefer-lowest" - -install: - - if [[ "${TRAVIS_PHP_VERSION}" == "5.5" ]]; then composer require phpunit/phpunit:^4.8.36 phpspec/phpspec:^2 --prefer-dist --update-with-dependencies; fi - - if [[ "${TRAVIS_PHP_VERSION}" == "7.2" ]]; then composer require phpunit/phpunit:^6.0 --prefer-dist --update-with-dependencies; fi - - travis_retry composer update --prefer-dist $COMPOSER_OPTS - -script: - - vendor/bin/phpspec run - - vendor/bin/phpunit - -after_script: - - wget https://scrutinizer-ci.com/ocular.phar' - - php ocular.phar code-coverage:upload --format=php-clover ./clover/phpunit.xml' diff --git a/vendor/league/flysystem-cached-adapter/LICENSE b/vendor/league/flysystem-cached-adapter/LICENSE deleted file mode 100644 index 666f6c826..000000000 --- a/vendor/league/flysystem-cached-adapter/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 Frank de Jonge - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/league/flysystem-cached-adapter/clover/.gitignore b/vendor/league/flysystem-cached-adapter/clover/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/vendor/league/flysystem-cached-adapter/clover/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/vendor/league/flysystem-cached-adapter/composer.json b/vendor/league/flysystem-cached-adapter/composer.json deleted file mode 100644 index df7fb7fd9..000000000 --- a/vendor/league/flysystem-cached-adapter/composer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "league/flysystem-cached-adapter", - "description": "An adapter decorator to enable meta-data caching.", - "autoload": { - "psr-4": { - "League\\Flysystem\\Cached\\": "src/" - } - }, - "require": { - "league/flysystem": "~1.0", - "psr/cache": "^1.0.0" - }, - "require-dev": { - "phpspec/phpspec": "^3.4", - "phpunit/phpunit": "^5.7", - "mockery/mockery": "~0.9", - "predis/predis": "~1.0", - "tedivm/stash": "~0.12" - }, - "suggest": { - "ext-phpredis": "Pure C implemented extension for PHP" - }, - "license": "MIT", - "authors": [ - { - "name": "frankdejonge", - "email": "info@frenky.net" - } - ] -} diff --git a/vendor/league/flysystem-cached-adapter/phpspec.yml b/vendor/league/flysystem-cached-adapter/phpspec.yml deleted file mode 100644 index 5eabcb21b..000000000 --- a/vendor/league/flysystem-cached-adapter/phpspec.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -suites: - cached_adapter_suite: - namespace: League\Flysystem\Cached - psr4_prefix: League\Flysystem\Cached -formatter.name: pretty diff --git a/vendor/league/flysystem-cached-adapter/phpunit.php b/vendor/league/flysystem-cached-adapter/phpunit.php deleted file mode 100644 index d10958796..000000000 --- a/vendor/league/flysystem-cached-adapter/phpunit.php +++ /dev/null @@ -1,3 +0,0 @@ - - - - - ./tests/ - - - - - ./src/ - - - - - - - - diff --git a/vendor/league/flysystem-cached-adapter/readme.md b/vendor/league/flysystem-cached-adapter/readme.md deleted file mode 100644 index dd1433d98..000000000 --- a/vendor/league/flysystem-cached-adapter/readme.md +++ /dev/null @@ -1,20 +0,0 @@ -# Flysystem Cached CachedAdapter - -[![Author](http://img.shields.io/badge/author-@frankdejonge-blue.svg?style=flat-square)](https://twitter.com/frankdejonge) -[![Build Status](https://img.shields.io/travis/thephpleague/flysystem-cached-adapter/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/flysystem-cached-adapter) -[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/flysystem-cached-adapter.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/flysystem-cached-adapter/code-structure) -[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/flysystem-cached-adapter.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/flysystem-cached-adapter) -[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) -[![Packagist Version](https://img.shields.io/packagist/v/league/flysystem-cached-adapter.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-cached-adapter) -[![Total Downloads](https://img.shields.io/packagist/dt/league/flysystem-cached-adapter.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-cached-adapter) - - -The adapter decorator caches metadata and directory listings. - -```bash -composer require league/flysystem-cached-adapter -``` - -## Usage - -[Check out the docs.](https://flysystem.thephpleague.com/docs/advanced/caching/) diff --git a/vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php b/vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php deleted file mode 100644 index 69428d990..000000000 --- a/vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php +++ /dev/null @@ -1,435 +0,0 @@ -adapter = $adapter; - $this->cache = $cache; - $this->cache->load()->shouldBeCalled(); - $this->beConstructedWith($adapter, $cache); - } - - public function it_is_initializable() - { - $this->shouldHaveType('League\Flysystem\Cached\CachedAdapter'); - $this->shouldHaveType('League\Flysystem\AdapterInterface'); - } - - public function it_should_forward_read_streams() - { - $path = 'path.txt'; - $response = ['path' => $path]; - $this->adapter->readStream($path)->willReturn($response); - $this->readStream($path)->shouldbe($response); - } - - public function it_should_cache_writes() - { - $type = 'file'; - $path = 'path.txt'; - $contents = 'contents'; - $config = new Config(); - $response = compact('path', 'contents', 'type'); - $this->adapter->write($path, $contents, $config)->willReturn($response); - $this->cache->updateObject($path, $response, true)->shouldBeCalled(); - $this->write($path, $contents, $config)->shouldBe($response); - } - - public function it_should_cache_streamed_writes() - { - $type = 'file'; - $path = 'path.txt'; - $stream = tmpfile(); - $config = new Config(); - $response = compact('path', 'stream', 'type'); - $this->adapter->writeStream($path, $stream, $config)->willReturn($response); - $this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled(); - $this->writeStream($path, $stream, $config)->shouldBe($response); - fclose($stream); - } - - public function it_should_cache_streamed_updates() - { - $type = 'file'; - $path = 'path.txt'; - $stream = tmpfile(); - $config = new Config(); - $response = compact('path', 'stream', 'type'); - $this->adapter->updateStream($path, $stream, $config)->willReturn($response); - $this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled(); - $this->updateStream($path, $stream, $config)->shouldBe($response); - fclose($stream); - } - - public function it_should_ignore_failed_writes() - { - $path = 'path.txt'; - $contents = 'contents'; - $config = new Config(); - $this->adapter->write($path, $contents, $config)->willReturn(false); - $this->write($path, $contents, $config)->shouldBe(false); - } - - public function it_should_ignore_failed_streamed_writes() - { - $path = 'path.txt'; - $contents = tmpfile(); - $config = new Config(); - $this->adapter->writeStream($path, $contents, $config)->willReturn(false); - $this->writeStream($path, $contents, $config)->shouldBe(false); - fclose($contents); - } - - public function it_should_cache_updated() - { - $type = 'file'; - $path = 'path.txt'; - $contents = 'contents'; - $config = new Config(); - $response = compact('path', 'contents', 'type'); - $this->adapter->update($path, $contents, $config)->willReturn($response); - $this->cache->updateObject($path, $response, true)->shouldBeCalled(); - $this->update($path, $contents, $config)->shouldBe($response); - } - - public function it_should_ignore_failed_updates() - { - $path = 'path.txt'; - $contents = 'contents'; - $config = new Config(); - $this->adapter->update($path, $contents, $config)->willReturn(false); - $this->update($path, $contents, $config)->shouldBe(false); - } - - public function it_should_ignore_failed_streamed_updates() - { - $path = 'path.txt'; - $contents = tmpfile(); - $config = new Config(); - $this->adapter->updateStream($path, $contents, $config)->willReturn(false); - $this->updateStream($path, $contents, $config)->shouldBe(false); - fclose($contents); - } - - public function it_should_cache_renames() - { - $old = 'old.txt'; - $new = 'new.txt'; - $this->adapter->rename($old, $new)->willReturn(true); - $this->cache->rename($old, $new)->shouldBeCalled(); - $this->rename($old, $new)->shouldBe(true); - } - - public function it_should_ignore_rename_fails() - { - $old = 'old.txt'; - $new = 'new.txt'; - $this->adapter->rename($old, $new)->willReturn(false); - $this->rename($old, $new)->shouldBe(false); - } - - public function it_should_cache_copies() - { - $old = 'old.txt'; - $new = 'new.txt'; - $this->adapter->copy($old, $new)->willReturn(true); - $this->cache->copy($old, $new)->shouldBeCalled(); - $this->copy($old, $new)->shouldBe(true); - } - - public function it_should_ignore_copy_fails() - { - $old = 'old.txt'; - $new = 'new.txt'; - $this->adapter->copy($old, $new)->willReturn(false); - $this->copy($old, $new)->shouldBe(false); - } - - public function it_should_cache_deletes() - { - $delete = 'delete.txt'; - $this->adapter->delete($delete)->willReturn(true); - $this->cache->delete($delete)->shouldBeCalled(); - $this->delete($delete)->shouldBe(true); - } - - public function it_should_ignore_delete_fails() - { - $delete = 'delete.txt'; - $this->adapter->delete($delete)->willReturn(false); - $this->delete($delete)->shouldBe(false); - } - - public function it_should_cache_dir_deletes() - { - $delete = 'delete'; - $this->adapter->deleteDir($delete)->willReturn(true); - $this->cache->deleteDir($delete)->shouldBeCalled(); - $this->deleteDir($delete)->shouldBe(true); - } - - public function it_should_ignore_delete_dir_fails() - { - $delete = 'delete'; - $this->adapter->deleteDir($delete)->willReturn(false); - $this->deleteDir($delete)->shouldBe(false); - } - - public function it_should_cache_dir_creates() - { - $dirname = 'dirname'; - $config = new Config(); - $response = ['path' => $dirname, 'type' => 'dir']; - $this->adapter->createDir($dirname, $config)->willReturn($response); - $this->cache->updateObject($dirname, $response, true)->shouldBeCalled(); - $this->createDir($dirname, $config)->shouldBe($response); - } - - public function it_should_ignore_create_dir_fails() - { - $dirname = 'dirname'; - $config = new Config(); - $this->adapter->createDir($dirname, $config)->willReturn(false); - $this->createDir($dirname, $config)->shouldBe(false); - } - - public function it_should_cache_set_visibility() - { - $path = 'path.txt'; - $visibility = AdapterInterface::VISIBILITY_PUBLIC; - $this->adapter->setVisibility($path, $visibility)->willReturn(true); - $this->cache->updateObject($path, ['path' => $path, 'visibility' => $visibility], true)->shouldBeCalled(); - $this->setVisibility($path, $visibility)->shouldBe(true); - } - - public function it_should_ignore_set_visibility_fails() - { - $dirname = 'delete'; - $visibility = AdapterInterface::VISIBILITY_PUBLIC; - $this->adapter->setVisibility($dirname, $visibility)->willReturn(false); - $this->setVisibility($dirname, $visibility)->shouldBe(false); - } - - public function it_should_indicate_missing_files() - { - $this->cache->has($path = 'path.txt')->willReturn(false); - $this->has($path)->shouldBe(false); - } - - public function it_should_indicate_file_existance() - { - $this->cache->has($path = 'path.txt')->willReturn(true); - $this->has($path)->shouldBe(true); - } - - public function it_should_cache_missing_files() - { - $this->cache->has($path = 'path.txt')->willReturn(null); - $this->adapter->has($path)->willReturn(false); - $this->cache->storeMiss($path)->shouldBeCalled(); - $this->has($path)->shouldBe(false); - } - - public function it_should_delete_when_metadata_is_missing() - { - $path = 'path.txt'; - $this->cache->has($path)->willReturn(true); - $this->cache->getSize($path)->willReturn(['path' => $path]); - $this->adapter->getSize($path)->willReturn($response = ['path' => $path, 'size' => 1024]); - $this->cache->updateObject($path, $response, true)->shouldBeCalled(); - $this->getSize($path)->shouldBe($response); - } - - public function it_should_cache_has() - { - $this->cache->has($path = 'path.txt')->willReturn(null); - $this->adapter->has($path)->willReturn(true); - $this->cache->updateObject($path, compact('path'), true)->shouldBeCalled(); - $this->has($path)->shouldBe(true); - } - - public function it_should_list_cached_contents() - { - $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(true); - $response = [['path' => 'path.txt']]; - $this->cache->listContents($dirname, $recursive)->willReturn($response); - $this->listContents($dirname, $recursive)->shouldBe($response); - } - - public function it_should_ignore_failed_list_contents() - { - $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false); - $this->adapter->listContents($dirname, $recursive)->willReturn(false); - $this->listContents($dirname, $recursive)->shouldBe(false); - } - - public function it_should_cache_contents_listings() - { - $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false); - $response = [['path' => 'path.txt']]; - $this->adapter->listContents($dirname, $recursive)->willReturn($response); - $this->cache->storeContents($dirname, $response, $recursive)->shouldBeCalled(); - $this->listContents($dirname, $recursive)->shouldBe($response); - } - - public function it_should_use_cached_visibility() - { - $this->make_it_use_getter_cache('getVisibility', 'path.txt', [ - 'path' => 'path.txt', - 'visibility' => AdapterInterface::VISIBILITY_PUBLIC, - ]); - } - - public function it_should_cache_get_visibility() - { - $path = 'path.txt'; - $response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path]; - $this->make_it_cache_getter('getVisibility', $path, $response); - } - - public function it_should_ignore_failed_get_visibility() - { - $path = 'path.txt'; - $this->make_it_ignore_failed_getter('getVisibility', $path); - } - - public function it_should_use_cached_timestamp() - { - $this->make_it_use_getter_cache('getTimestamp', 'path.txt', [ - 'path' => 'path.txt', - 'timestamp' => 1234, - ]); - } - - public function it_should_cache_timestamps() - { - $this->make_it_cache_getter('getTimestamp', 'path.txt', [ - 'path' => 'path.txt', - 'timestamp' => 1234, - ]); - } - - public function it_should_ignore_failed_get_timestamps() - { - $this->make_it_ignore_failed_getter('getTimestamp', 'path.txt'); - } - - public function it_should_cache_get_metadata() - { - $path = 'path.txt'; - $response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path]; - $this->make_it_cache_getter('getMetadata', $path, $response); - } - - public function it_should_use_cached_metadata() - { - $this->make_it_use_getter_cache('getMetadata', 'path.txt', [ - 'path' => 'path.txt', - 'timestamp' => 1234, - ]); - } - - public function it_should_ignore_failed_get_metadata() - { - $this->make_it_ignore_failed_getter('getMetadata', 'path.txt'); - } - - public function it_should_cache_get_size() - { - $path = 'path.txt'; - $response = ['size' => 1234, 'path' => $path]; - $this->make_it_cache_getter('getSize', $path, $response); - } - - public function it_should_use_cached_size() - { - $this->make_it_use_getter_cache('getSize', 'path.txt', [ - 'path' => 'path.txt', - 'size' => 1234, - ]); - } - - public function it_should_ignore_failed_get_size() - { - $this->make_it_ignore_failed_getter('getSize', 'path.txt'); - } - - public function it_should_cache_get_mimetype() - { - $path = 'path.txt'; - $response = ['mimetype' => 'text/plain', 'path' => $path]; - $this->make_it_cache_getter('getMimetype', $path, $response); - } - - public function it_should_use_cached_mimetype() - { - $this->make_it_use_getter_cache('getMimetype', 'path.txt', [ - 'path' => 'path.txt', - 'mimetype' => 'text/plain', - ]); - } - - public function it_should_ignore_failed_get_mimetype() - { - $this->make_it_ignore_failed_getter('getMimetype', 'path.txt'); - } - - public function it_should_cache_reads() - { - $path = 'path.txt'; - $response = ['path' => $path, 'contents' => 'contents']; - $this->make_it_cache_getter('read', $path, $response); - } - - public function it_should_use_cached_file_contents() - { - $this->make_it_use_getter_cache('read', 'path.txt', [ - 'path' => 'path.txt', - 'contents' => 'contents' - ]); - } - - public function it_should_ignore_failed_reads() - { - $this->make_it_ignore_failed_getter('read', 'path.txt'); - } - - protected function make_it_use_getter_cache($method, $path, $response) - { - $this->cache->{$method}($path)->willReturn($response); - $this->{$method}($path)->shouldBe($response); - } - - protected function make_it_cache_getter($method, $path, $response) - { - $this->cache->{$method}($path)->willReturn(false); - $this->adapter->{$method}($path)->willReturn($response); - $this->cache->updateObject($path, $response, true)->shouldBeCalled(); - $this->{$method}($path)->shouldBe($response); - } - - protected function make_it_ignore_failed_getter($method, $path) - { - $this->cache->{$method}($path)->willReturn(false); - $this->adapter->{$method}($path)->willReturn(false); - $this->{$method}($path)->shouldBe(false); - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/CacheInterface.php b/vendor/league/flysystem-cached-adapter/src/CacheInterface.php deleted file mode 100644 index de3ab3d90..000000000 --- a/vendor/league/flysystem-cached-adapter/src/CacheInterface.php +++ /dev/null @@ -1,101 +0,0 @@ -adapter = $adapter; - $this->cache = $cache; - $this->cache->load(); - } - - /** - * Get the underlying Adapter implementation. - * - * @return AdapterInterface - */ - public function getAdapter() - { - return $this->adapter; - } - - /** - * Get the used Cache implementation. - * - * @return CacheInterface - */ - public function getCache() - { - return $this->cache; - } - - /** - * {@inheritdoc} - */ - public function write($path, $contents, Config $config) - { - $result = $this->adapter->write($path, $contents, $config); - - if ($result !== false) { - $result['type'] = 'file'; - $this->cache->updateObject($path, $result + compact('path', 'contents'), true); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function writeStream($path, $resource, Config $config) - { - $result = $this->adapter->writeStream($path, $resource, $config); - - if ($result !== false) { - $result['type'] = 'file'; - $contents = false; - $this->cache->updateObject($path, $result + compact('path', 'contents'), true); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function update($path, $contents, Config $config) - { - $result = $this->adapter->update($path, $contents, $config); - - if ($result !== false) { - $result['type'] = 'file'; - $this->cache->updateObject($path, $result + compact('path', 'contents'), true); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function updateStream($path, $resource, Config $config) - { - $result = $this->adapter->updateStream($path, $resource, $config); - - if ($result !== false) { - $result['type'] = 'file'; - $contents = false; - $this->cache->updateObject($path, $result + compact('path', 'contents'), true); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function rename($path, $newPath) - { - $result = $this->adapter->rename($path, $newPath); - - if ($result !== false) { - $this->cache->rename($path, $newPath); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function copy($path, $newpath) - { - $result = $this->adapter->copy($path, $newpath); - - if ($result !== false) { - $this->cache->copy($path, $newpath); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function delete($path) - { - $result = $this->adapter->delete($path); - - if ($result !== false) { - $this->cache->delete($path); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function deleteDir($dirname) - { - $result = $this->adapter->deleteDir($dirname); - - if ($result !== false) { - $this->cache->deleteDir($dirname); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function createDir($dirname, Config $config) - { - $result = $this->adapter->createDir($dirname, $config); - - if ($result !== false) { - $type = 'dir'; - $path = $dirname; - $this->cache->updateObject($dirname, compact('path', 'type'), true); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function setVisibility($path, $visibility) - { - $result = $this->adapter->setVisibility($path, $visibility); - - if ($result !== false) { - $this->cache->updateObject($path, compact('path', 'visibility'), true); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function has($path) - { - $cacheHas = $this->cache->has($path); - - if ($cacheHas !== null) { - return $cacheHas; - } - - $adapterResponse = $this->adapter->has($path); - - if (! $adapterResponse) { - $this->cache->storeMiss($path); - } else { - $cacheEntry = is_array($adapterResponse) ? $adapterResponse : compact('path'); - $this->cache->updateObject($path, $cacheEntry, true); - } - - return $adapterResponse; - } - - /** - * {@inheritdoc} - */ - public function read($path) - { - return $this->callWithFallback('contents', $path, 'read'); - } - - /** - * {@inheritdoc} - */ - public function readStream($path) - { - return $this->adapter->readStream($path); - } - - /** - * Get the path prefix. - * - * @return string|null path prefix or null if pathPrefix is empty - */ - public function getPathPrefix() - { - return $this->adapter->getPathPrefix(); - } - - /** - * Prefix a path. - * - * @param string $path - * - * @return string prefixed path - */ - public function applyPathPrefix($path) - { - return $this->adapter->applyPathPrefix($path); - } - - /** - * {@inheritdoc} - */ - public function listContents($directory = '', $recursive = false) - { - if ($this->cache->isComplete($directory, $recursive)) { - return $this->cache->listContents($directory, $recursive); - } - - $result = $this->adapter->listContents($directory, $recursive); - - if ($result !== false) { - $this->cache->storeContents($directory, $result, $recursive); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function getMetadata($path) - { - return $this->callWithFallback(null, $path, 'getMetadata'); - } - - /** - * {@inheritdoc} - */ - public function getSize($path) - { - return $this->callWithFallback('size', $path, 'getSize'); - } - - /** - * {@inheritdoc} - */ - public function getMimetype($path) - { - return $this->callWithFallback('mimetype', $path, 'getMimetype'); - } - - /** - * {@inheritdoc} - */ - public function getTimestamp($path) - { - return $this->callWithFallback('timestamp', $path, 'getTimestamp'); - } - - /** - * {@inheritdoc} - */ - public function getVisibility($path) - { - return $this->callWithFallback('visibility', $path, 'getVisibility'); - } - - /** - * Call a method and cache the response. - * - * @param string $property - * @param string $path - * @param string $method - * - * @return mixed - */ - protected function callWithFallback($property, $path, $method) - { - $result = $this->cache->{$method}($path); - - if ($result !== false && ($property === null || array_key_exists($property, $result))) { - return $result; - } - - $result = $this->adapter->{$method}($path); - - if ($result) { - $object = $result + compact('path'); - $this->cache->updateObject($path, $object, true); - } - - return $result; - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php b/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php deleted file mode 100644 index 141b46822..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php +++ /dev/null @@ -1,418 +0,0 @@ -autosave) { - $this->save(); - } - } - - /** - * Get the autosave setting. - * - * @return bool autosave - */ - public function getAutosave() - { - return $this->autosave; - } - - /** - * Get the autosave setting. - * - * @param bool $autosave - */ - public function setAutosave($autosave) - { - $this->autosave = $autosave; - } - - /** - * Store the contents listing. - * - * @param string $directory - * @param array $contents - * @param bool $recursive - * - * @return array contents listing - */ - public function storeContents($directory, array $contents, $recursive = false) - { - $directories = [$directory]; - - foreach ($contents as $object) { - $this->updateObject($object['path'], $object); - $object = $this->cache[$object['path']]; - - if ($recursive && $this->pathIsInDirectory($directory, $object['path'])) { - $directories[] = $object['dirname']; - } - } - - foreach (array_unique($directories) as $directory) { - $this->setComplete($directory, $recursive); - } - - $this->autosave(); - } - - /** - * Update the metadata for an object. - * - * @param string $path object path - * @param array $object object metadata - * @param bool $autosave whether to trigger the autosave routine - */ - public function updateObject($path, array $object, $autosave = false) - { - if (! $this->has($path)) { - $this->cache[$path] = Util::pathinfo($path); - } - - $this->cache[$path] = array_merge($this->cache[$path], $object); - - if ($autosave) { - $this->autosave(); - } - - $this->ensureParentDirectories($path); - } - - /** - * Store object hit miss. - * - * @param string $path - */ - public function storeMiss($path) - { - $this->cache[$path] = false; - $this->autosave(); - } - - /** - * Get the contents listing. - * - * @param string $dirname - * @param bool $recursive - * - * @return array contents listing - */ - public function listContents($dirname = '', $recursive = false) - { - $result = []; - - foreach ($this->cache as $object) { - if ($object === false) { - continue; - } - if ($object['dirname'] === $dirname) { - $result[] = $object; - } elseif ($recursive && $this->pathIsInDirectory($dirname, $object['path'])) { - $result[] = $object; - } - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function has($path) - { - if ($path !== false && array_key_exists($path, $this->cache)) { - return $this->cache[$path] !== false; - } - - if ($this->isComplete(Util::dirname($path), false)) { - return false; - } - } - - /** - * {@inheritdoc} - */ - public function read($path) - { - if (isset($this->cache[$path]['contents']) && $this->cache[$path]['contents'] !== false) { - return $this->cache[$path]; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function readStream($path) - { - return false; - } - - /** - * {@inheritdoc} - */ - public function rename($path, $newpath) - { - if ($this->has($path)) { - $object = $this->cache[$path]; - unset($this->cache[$path]); - $object['path'] = $newpath; - $object = array_merge($object, Util::pathinfo($newpath)); - $this->cache[$newpath] = $object; - $this->autosave(); - } - } - - /** - * {@inheritdoc} - */ - public function copy($path, $newpath) - { - if ($this->has($path)) { - $object = $this->cache[$path]; - $object = array_merge($object, Util::pathinfo($newpath)); - $this->updateObject($newpath, $object, true); - } - } - - /** - * {@inheritdoc} - */ - public function delete($path) - { - $this->storeMiss($path); - } - - /** - * {@inheritdoc} - */ - public function deleteDir($dirname) - { - foreach ($this->cache as $path => $object) { - if ($this->pathIsInDirectory($dirname, $path) || $path === $dirname) { - unset($this->cache[$path]); - } - } - - unset($this->complete[$dirname]); - - $this->autosave(); - } - - /** - * {@inheritdoc} - */ - public function getMimetype($path) - { - if (isset($this->cache[$path]['mimetype'])) { - return $this->cache[$path]; - } - - if (! $result = $this->read($path)) { - return false; - } - - $mimetype = Util::guessMimeType($path, $result['contents']); - $this->cache[$path]['mimetype'] = $mimetype; - - return $this->cache[$path]; - } - - /** - * {@inheritdoc} - */ - public function getSize($path) - { - if (isset($this->cache[$path]['size'])) { - return $this->cache[$path]; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function getTimestamp($path) - { - if (isset($this->cache[$path]['timestamp'])) { - return $this->cache[$path]; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function getVisibility($path) - { - if (isset($this->cache[$path]['visibility'])) { - return $this->cache[$path]; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function getMetadata($path) - { - if (isset($this->cache[$path]['type'])) { - return $this->cache[$path]; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function isComplete($dirname, $recursive) - { - if (! array_key_exists($dirname, $this->complete)) { - return false; - } - - if ($recursive && $this->complete[$dirname] !== 'recursive') { - return false; - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function setComplete($dirname, $recursive) - { - $this->complete[$dirname] = $recursive ? 'recursive' : true; - } - - /** - * Filter the contents from a listing. - * - * @param array $contents object listing - * - * @return array filtered contents - */ - public function cleanContents(array $contents) - { - $cachedProperties = array_flip([ - 'path', 'dirname', 'basename', 'extension', 'filename', - 'size', 'mimetype', 'visibility', 'timestamp', 'type', - 'md5', - ]); - - foreach ($contents as $path => $object) { - if (is_array($object)) { - $contents[$path] = array_intersect_key($object, $cachedProperties); - } - } - - return $contents; - } - - /** - * {@inheritdoc} - */ - public function flush() - { - $this->cache = []; - $this->complete = []; - $this->autosave(); - } - - /** - * {@inheritdoc} - */ - public function autosave() - { - if ($this->autosave) { - $this->save(); - } - } - - /** - * Retrieve serialized cache data. - * - * @return string serialized data - */ - public function getForStorage() - { - $cleaned = $this->cleanContents($this->cache); - - return json_encode([$cleaned, $this->complete]); - } - - /** - * Load from serialized cache data. - * - * @param string $json - */ - public function setFromStorage($json) - { - list($cache, $complete) = json_decode($json, true); - - if (json_last_error() === JSON_ERROR_NONE && is_array($cache) && is_array($complete)) { - $this->cache = $cache; - $this->complete = $complete; - } - } - - /** - * Ensure parent directories of an object. - * - * @param string $path object path - */ - public function ensureParentDirectories($path) - { - $object = $this->cache[$path]; - - while ($object['dirname'] !== '' && ! isset($this->cache[$object['dirname']])) { - $object = Util::pathinfo($object['dirname']); - $object['type'] = 'dir'; - $this->cache[$object['path']] = $object; - } - } - - /** - * Determines if the path is inside the directory. - * - * @param string $directory - * @param string $path - * - * @return bool - */ - protected function pathIsInDirectory($directory, $path) - { - return $directory === '' || strpos($path, $directory . '/') === 0; - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php b/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php deleted file mode 100644 index 649a60e3b..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php +++ /dev/null @@ -1,115 +0,0 @@ -adapter = $adapter; - $this->file = $file; - $this->setExpire($expire); - } - - /** - * Set the expiration time in seconds. - * - * @param int $expire relative expiration time - */ - protected function setExpire($expire) - { - if ($expire) { - $this->expire = $this->getTime($expire); - } - } - - /** - * Get expiration time in seconds. - * - * @param int $time relative expiration time - * - * @return int actual expiration time - */ - protected function getTime($time = 0) - { - return intval(microtime(true)) + $time; - } - - /** - * {@inheritdoc} - */ - public function setFromStorage($json) - { - list($cache, $complete, $expire) = json_decode($json, true); - - if (! $expire || $expire > $this->getTime()) { - $this->cache = is_array($cache) ? $cache : []; - $this->complete = is_array($complete) ? $complete : []; - } else { - $this->adapter->delete($this->file); - } - } - - /** - * {@inheritdoc} - */ - public function load() - { - if ($this->adapter->has($this->file)) { - $file = $this->adapter->read($this->file); - if ($file && !empty($file['contents'])) { - $this->setFromStorage($file['contents']); - } - } - } - - /** - * {@inheritdoc} - */ - public function getForStorage() - { - $cleaned = $this->cleanContents($this->cache); - - return json_encode([$cleaned, $this->complete, $this->expire]); - } - - /** - * {@inheritdoc} - */ - public function save() - { - $config = new Config(); - $contents = $this->getForStorage(); - - if ($this->adapter->has($this->file)) { - $this->adapter->update($this->file, $contents, $config); - } else { - $this->adapter->write($this->file, $contents, $config); - } - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php b/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php deleted file mode 100644 index f67d2717a..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php +++ /dev/null @@ -1,59 +0,0 @@ -key = $key; - $this->expire = $expire; - $this->memcached = $memcached; - } - - /** - * {@inheritdoc} - */ - public function load() - { - $contents = $this->memcached->get($this->key); - - if ($contents !== false) { - $this->setFromStorage($contents); - } - } - - /** - * {@inheritdoc} - */ - public function save() - { - $contents = $this->getForStorage(); - $expiration = $this->expire === null ? 0 : time() + $this->expire; - $this->memcached->set($this->key, $contents, $expiration); - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php b/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php deleted file mode 100644 index d0914fabd..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php +++ /dev/null @@ -1,22 +0,0 @@ -client = $client ?: new Redis(); - $this->key = $key; - $this->expire = $expire; - } - - /** - * {@inheritdoc} - */ - public function load() - { - $contents = $this->client->get($this->key); - - if ($contents !== false) { - $this->setFromStorage($contents); - } - } - - /** - * {@inheritdoc} - */ - public function save() - { - $contents = $this->getForStorage(); - $this->client->set($this->key, $contents); - - if ($this->expire !== null) { - $this->client->expire($this->key, $this->expire); - } - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php b/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php deleted file mode 100644 index 8a295744b..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php +++ /dev/null @@ -1,75 +0,0 @@ -client = $client ?: new Client(); - $this->key = $key; - $this->expire = $expire; - } - - /** - * {@inheritdoc} - */ - public function load() - { - if (($contents = $this->executeCommand('get', [$this->key])) !== null) { - $this->setFromStorage($contents); - } - } - - /** - * {@inheritdoc} - */ - public function save() - { - $contents = $this->getForStorage(); - $this->executeCommand('set', [$this->key, $contents]); - - if ($this->expire !== null) { - $this->executeCommand('expire', [$this->key, $this->expire]); - } - } - - /** - * Execute a Predis command. - * - * @param string $name - * @param array $arguments - * - * @return string - */ - protected function executeCommand($name, array $arguments) - { - $command = $this->client->createCommand($name, $arguments); - - return $this->client->executeCommand($command); - } -} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php b/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php deleted file mode 100644 index 43be87e53..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php +++ /dev/null @@ -1,59 +0,0 @@ -pool = $pool; - $this->key = $key; - $this->expire = $expire; - } - - /** - * {@inheritdoc} - */ - public function save() - { - $item = $this->pool->getItem($this->key); - $item->set($this->getForStorage()); - $item->expiresAfter($this->expire); - $this->pool->save($item); - } - - /** - * {@inheritdoc} - */ - public function load() - { - $item = $this->pool->getItem($this->key); - if ($item->isHit()) { - $this->setFromStorage($item->get()); - } - } -} \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php b/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php deleted file mode 100644 index e05b83228..000000000 --- a/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php +++ /dev/null @@ -1,60 +0,0 @@ -key = $key; - $this->expire = $expire; - $this->pool = $pool; - } - - /** - * {@inheritdoc} - */ - public function load() - { - $item = $this->pool->getItem($this->key); - $contents = $item->get(); - - if ($item->isMiss() === false) { - $this->setFromStorage($contents); - } - } - - /** - * {@inheritdoc} - */ - public function save() - { - $contents = $this->getForStorage(); - $item = $this->pool->getItem($this->key); - $item->set($contents, $this->expire); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php b/vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php deleted file mode 100644 index b63cba788..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php +++ /dev/null @@ -1,104 +0,0 @@ -shouldReceive('has')->once()->with('file.json')->andReturn(false); - $cache = new Adapter($adapter, 'file.json', 10); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadExpired() - { - $response = ['contents' => json_encode([[], ['' => true], 1234567890]), 'path' => 'file.json']; - $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); - $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true); - $adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response); - $adapter->shouldReceive('delete')->once()->with('file.json'); - $cache = new Adapter($adapter, 'file.json', 10); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadSuccess() - { - $response = ['contents' => json_encode([[], ['' => true], 9876543210]), 'path' => 'file.json']; - $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); - $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true); - $adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response); - $cache = new Adapter($adapter, 'file.json', 10); - $cache->load(); - $this->assertTrue($cache->isComplete('', false)); - } - - public function testSaveExists() - { - $response = json_encode([[], [], null]); - $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); - $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true); - $adapter->shouldReceive('update')->once()->with('file.json', $response, Mockery::any()); - $cache = new Adapter($adapter, 'file.json', null); - $cache->save(); - } - - public function testSaveNew() - { - $response = json_encode([[], [], null]); - $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); - $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false); - $adapter->shouldReceive('write')->once()->with('file.json', $response, Mockery::any()); - $cache = new Adapter($adapter, 'file.json', null); - $cache->save(); - } - - public function testStoreContentsRecursive() - { - $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); - $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false); - $adapter->shouldReceive('write')->once()->with('file.json', Mockery::any(), Mockery::any()); - - $cache = new Adapter($adapter, 'file.json', null); - - $contents = [ - ['path' => 'foo/bar', 'dirname' => 'foo'], - ['path' => 'afoo/bang', 'dirname' => 'afoo'], - ]; - - $cache->storeContents('foo', $contents, true); - - $this->assertTrue($cache->isComplete('foo', true)); - $this->assertFalse($cache->isComplete('afoo', true)); - } - - public function testDeleteDir() - { - $cache_data = [ - 'foo' => ['path' => 'foo', 'type' => 'dir', 'dirname' => ''], - 'foo/bar' => ['path' => 'foo/bar', 'type' => 'file', 'dirname' => 'foo'], - 'foobaz' => ['path' => 'foobaz', 'type' => 'file', 'dirname' => ''], - ]; - - $response = [ - 'contents' => json_encode([$cache_data, [], null]), - 'path' => 'file.json', - ]; - - $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); - $adapter->shouldReceive('has')->zeroOrMoreTimes()->with('file.json')->andReturn(true); - $adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response); - $adapter->shouldReceive('update')->once()->with('file.json', Mockery::any(), Mockery::any())->andReturn(true); - - $cache = new Adapter($adapter, 'file.json', null); - $cache->load(); - - $cache->deleteDir('foo', true); - - $this->assertSame(1, count($cache->listContents('', true))); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/InspectionTests.php b/vendor/league/flysystem-cached-adapter/tests/InspectionTests.php deleted file mode 100644 index 40d4c915e..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/InspectionTests.php +++ /dev/null @@ -1,16 +0,0 @@ -shouldReceive('load')->once(); - $cached_adapter = new CachedAdapter($adapter, $cache); - $this->assertInstanceOf('League\Flysystem\AdapterInterface', $cached_adapter->getAdapter()); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php b/vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php deleted file mode 100644 index e3d9ad939..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php +++ /dev/null @@ -1,35 +0,0 @@ -shouldReceive('get')->once()->andReturn(false); - $cache = new Memcached($client); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadSuccess() - { - $response = json_encode([[], ['' => true]]); - $client = Mockery::mock('Memcached'); - $client->shouldReceive('get')->once()->andReturn($response); - $cache = new Memcached($client); - $cache->load(); - $this->assertTrue($cache->isComplete('', false)); - } - - public function testSave() - { - $response = json_encode([[], []]); - $client = Mockery::mock('Memcached'); - $client->shouldReceive('set')->once()->andReturn($response); - $cache = new Memcached($client); - $cache->save(); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php b/vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php deleted file mode 100644 index 3ac58fd08..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php +++ /dev/null @@ -1,255 +0,0 @@ -setAutosave(true); - $this->assertTrue($cache->getAutosave()); - $cache->setAutosave(false); - $this->assertFalse($cache->getAutosave()); - } - - public function testCacheMiss() - { - $cache = new Memory(); - $cache->storeMiss('path.txt'); - $this->assertFalse($cache->has('path.txt')); - } - - public function testIsComplete() - { - $cache = new Memory(); - $this->assertFalse($cache->isComplete('dirname', false)); - $cache->setComplete('dirname', false); - $this->assertFalse($cache->isComplete('dirname', true)); - $cache->setComplete('dirname', true); - $this->assertTrue($cache->isComplete('dirname', true)); - } - - public function testCleanContents() - { - $cache = new Memory(); - $input = [[ - 'path' => 'path.txt', - 'visibility' => 'public', - 'invalid' => 'thing', - ]]; - - $expected = [[ - 'path' => 'path.txt', - 'visibility' => 'public', - ]]; - - $output = $cache->cleanContents($input); - $this->assertEquals($expected, $output); - } - - public function testGetForStorage() - { - $cache = new Memory(); - $input = [[ - 'path' => 'path.txt', - 'visibility' => 'public', - 'type' => 'file', - ]]; - - $cache->storeContents('', $input, true); - $contents = $cache->listContents('', true); - $cached = []; - foreach ($contents as $item) { - $cached[$item['path']] = $item; - } - - $this->assertEquals(json_encode([$cached, ['' => 'recursive']]), $cache->getForStorage()); - } - - public function testParentCompleteIsUsedDuringHas() - { - $cache = new Memory(); - $cache->setComplete('dirname', false); - $this->assertFalse($cache->has('dirname/path.txt')); - } - - public function testFlush() - { - $cache = new Memory(); - $cache->setComplete('dirname', true); - $cache->updateObject('path.txt', [ - 'path' => 'path.txt', - 'visibility' => 'public', - ]); - $cache->flush(); - $this->assertFalse($cache->isComplete('dirname', true)); - $this->assertNull($cache->has('path.txt')); - } - - public function testSetFromStorage() - { - $cache = new Memory(); - $json = [[ - 'path.txt' => ['path' => 'path.txt', 'type' => 'file'], - ], ['dirname' => 'recursive']]; - $jsonString = json_encode($json); - $cache->setFromStorage($jsonString); - $this->assertTrue($cache->has('path.txt')); - $this->assertTrue($cache->isComplete('dirname', true)); - } - - public function testGetMetadataFail() - { - $cache = new Memory(); - $this->assertFalse($cache->getMetadata('path.txt')); - } - - public function metaGetterProvider() - { - return [ - ['getTimestamp', 'timestamp', 12344], - ['getMimetype', 'mimetype', 'text/plain'], - ['getSize', 'size', 12], - ['getVisibility', 'visibility', 'private'], - ['read', 'contents', '__contents__'], - ]; - } - - /** - * @dataProvider metaGetterProvider - * - * @param $method - * @param $key - * @param $value - */ - public function testMetaGetters($method, $key, $value) - { - $cache = new Memory(); - $this->assertFalse($cache->{$method}('path.txt')); - $cache->updateObject('path.txt', $object = [ - 'path' => 'path.txt', - 'type' => 'file', - $key => $value, - ] + Util::pathinfo('path.txt'), true); - $this->assertEquals($object, $cache->{$method}('path.txt')); - $this->assertEquals($object, $cache->getMetadata('path.txt')); - } - - public function testGetDerivedMimetype() - { - $cache = new Memory(); - $cache->updateObject('path.txt', [ - 'contents' => 'something', - ]); - $response = $cache->getMimetype('path.txt'); - $this->assertEquals('text/plain', $response['mimetype']); - } - - public function testCopyFail() - { - $cache = new Memory(); - $cache->copy('one', 'two'); - $this->assertNull($cache->has('two')); - $this->assertNull($cache->load()); - } - - public function testStoreContents() - { - $cache = new Memory(); - $cache->storeContents('dirname', [ - ['path' => 'dirname', 'type' => 'dir'], - ['path' => 'dirname/nested', 'type' => 'dir'], - ['path' => 'dirname/nested/deep', 'type' => 'dir'], - ['path' => 'other/nested/deep', 'type' => 'dir'], - ], true); - - $this->isTrue($cache->isComplete('other/nested', true)); - } - - public function testDelete() - { - $cache = new Memory(); - $cache->updateObject('path.txt', ['type' => 'file']); - $this->assertTrue($cache->has('path.txt')); - $cache->delete('path.txt'); - $this->assertFalse($cache->has('path.txt')); - } - - public function testDeleteDir() - { - $cache = new Memory(); - $cache->storeContents('dirname', [ - ['path' => 'dirname/path.txt', 'type' => 'file'], - ]); - $this->assertTrue($cache->isComplete('dirname', false)); - $this->assertTrue($cache->has('dirname/path.txt')); - $cache->deleteDir('dirname'); - $this->assertFalse($cache->isComplete('dirname', false)); - $this->assertNull($cache->has('dirname/path.txt')); - } - - public function testReadStream() - { - $cache = new Memory(); - $this->assertFalse($cache->readStream('path.txt')); - } - - public function testRename() - { - $cache = new Memory(); - $cache->updateObject('path.txt', ['type' => 'file']); - $cache->rename('path.txt', 'newpath.txt'); - $this->assertTrue($cache->has('newpath.txt')); - } - - public function testCopy() - { - $cache = new Memory(); - $cache->updateObject('path.txt', ['type' => 'file']); - $cache->copy('path.txt', 'newpath.txt'); - $this->assertTrue($cache->has('newpath.txt')); - } - - public function testComplextListContents() - { - $cache = new Memory(); - $cache->storeContents('', [ - ['path' => 'dirname', 'type' => 'dir'], - ['path' => 'dirname/file.txt', 'type' => 'file'], - ['path' => 'other', 'type' => 'dir'], - ['path' => 'other/file.txt', 'type' => 'file'], - ['path' => 'other/nested/file.txt', 'type' => 'file'], - ]); - - $this->assertCount(3, $cache->listContents('other', true)); - } - - public function testComplextListContentsWithDeletedFile() - { - $cache = new Memory(); - $cache->storeContents('', [ - ['path' => 'dirname', 'type' => 'dir'], - ['path' => 'dirname/file.txt', 'type' => 'file'], - ['path' => 'other', 'type' => 'dir'], - ['path' => 'other/file.txt', 'type' => 'file'], - ['path' => 'other/another_file.txt', 'type' => 'file'], - ]); - - $cache->delete('other/another_file.txt'); - $this->assertCount(4, $cache->listContents('', true)); - } - - public function testCacheMissIfContentsIsFalse() - { - $cache = new Memory(); - $cache->updateObject('path.txt', [ - 'path' => 'path.txt', - 'contents' => false, - ], true); - - $this->assertFalse($cache->read('path.txt')); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php b/vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php deleted file mode 100644 index 148616ff1..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php +++ /dev/null @@ -1,35 +0,0 @@ -assertEquals($cache, $cache->storeMiss('file.txt')); - $this->assertNull($cache->setComplete('', false)); - $this->assertNull($cache->load()); - $this->assertNull($cache->flush()); - $this->assertNull($cache->has('path.txt')); - $this->assertNull($cache->autosave()); - $this->assertFalse($cache->isComplete('', false)); - $this->assertFalse($cache->read('something')); - $this->assertFalse($cache->readStream('something')); - $this->assertFalse($cache->getMetadata('something')); - $this->assertFalse($cache->getMimetype('something')); - $this->assertFalse($cache->getSize('something')); - $this->assertFalse($cache->getTimestamp('something')); - $this->assertFalse($cache->getVisibility('something')); - $this->assertEmpty($cache->listContents('', false)); - $this->assertFalse($cache->rename('', '')); - $this->assertFalse($cache->copy('', '')); - $this->assertNull($cache->save()); - $object = ['path' => 'path.ext']; - $this->assertEquals($object, $cache->updateObject('path.txt', $object)); - $this->assertEquals([['path' => 'some/file.txt']], $cache->storeContents('unknwon', [ - ['path' => 'some/file.txt'], - ], false)); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php b/vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php deleted file mode 100644 index d1ccb6545..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php +++ /dev/null @@ -1,45 +0,0 @@ -shouldReceive('get')->with('flysystem')->once()->andReturn(false); - $cache = new PhpRedis($client); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadSuccess() - { - $response = json_encode([[], ['' => true]]); - $client = Mockery::mock('Redis'); - $client->shouldReceive('get')->with('flysystem')->once()->andReturn($response); - $cache = new PhpRedis($client); - $cache->load(); - $this->assertTrue($cache->isComplete('', false)); - } - - public function testSave() - { - $data = json_encode([[], []]); - $client = Mockery::mock('Redis'); - $client->shouldReceive('set')->with('flysystem', $data)->once(); - $cache = new PhpRedis($client); - $cache->save(); - } - - public function testSaveWithExpire() - { - $data = json_encode([[], []]); - $client = Mockery::mock('Redis'); - $client->shouldReceive('set')->with('flysystem', $data)->once(); - $client->shouldReceive('expire')->with('flysystem', 20)->once(); - $cache = new PhpRedis($client, 'flysystem', 20); - $cache->save(); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/PredisTests.php b/vendor/league/flysystem-cached-adapter/tests/PredisTests.php deleted file mode 100644 index e33e10468..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/PredisTests.php +++ /dev/null @@ -1,55 +0,0 @@ -shouldReceive('createCommand')->with('get', ['flysystem'])->once()->andReturn($command); - $client->shouldReceive('executeCommand')->with($command)->andReturn(null); - $cache = new Predis($client); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadSuccess() - { - $response = json_encode([[], ['' => true]]); - $client = Mockery::mock('Predis\Client'); - $command = Mockery::mock('Predis\Command\CommandInterface'); - $client->shouldReceive('createCommand')->with('get', ['flysystem'])->once()->andReturn($command); - $client->shouldReceive('executeCommand')->with($command)->andReturn($response); - $cache = new Predis($client); - $cache->load(); - $this->assertTrue($cache->isComplete('', false)); - } - - public function testSave() - { - $data = json_encode([[], []]); - $client = Mockery::mock('Predis\Client'); - $command = Mockery::mock('Predis\Command\CommandInterface'); - $client->shouldReceive('createCommand')->with('set', ['flysystem', $data])->once()->andReturn($command); - $client->shouldReceive('executeCommand')->with($command)->once(); - $cache = new Predis($client); - $cache->save(); - } - - public function testSaveWithExpire() - { - $data = json_encode([[], []]); - $client = Mockery::mock('Predis\Client'); - $command = Mockery::mock('Predis\Command\CommandInterface'); - $client->shouldReceive('createCommand')->with('set', ['flysystem', $data])->once()->andReturn($command); - $client->shouldReceive('executeCommand')->with($command)->once(); - $expireCommand = Mockery::mock('Predis\Command\CommandInterface'); - $client->shouldReceive('createCommand')->with('expire', ['flysystem', 20])->once()->andReturn($expireCommand); - $client->shouldReceive('executeCommand')->with($expireCommand)->once(); - $cache = new Predis($client, 'flysystem', 20); - $cache->save(); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php b/vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php deleted file mode 100644 index d5e5700cf..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php +++ /dev/null @@ -1,45 +0,0 @@ -shouldReceive('isHit')->once()->andReturn(false); - $pool->shouldReceive('getItem')->once()->andReturn($item); - $cache = new Psr6Cache($pool); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadSuccess() - { - $response = json_encode([[], ['' => true]]); - $pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface'); - $item = Mockery::mock('Psr\Cache\CacheItemInterface'); - $item->shouldReceive('get')->once()->andReturn($response); - $item->shouldReceive('isHit')->once()->andReturn(true); - $pool->shouldReceive('getItem')->once()->andReturn($item); - $cache = new Psr6Cache($pool); - $cache->load(); - $this->assertTrue($cache->isComplete('', false)); - } - - public function testSave() - { - $response = json_encode([[], []]); - $ttl = 4711; - $pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface'); - $item = Mockery::mock('Psr\Cache\CacheItemInterface'); - $item->shouldReceive('expiresAfter')->once()->with($ttl); - $item->shouldReceive('set')->once()->andReturn($response); - $pool->shouldReceive('getItem')->once()->andReturn($item); - $pool->shouldReceive('save')->once()->with($item); - $cache = new Psr6Cache($pool, 'foo', $ttl); - $cache->save(); - } -} diff --git a/vendor/league/flysystem-cached-adapter/tests/StashTest.php b/vendor/league/flysystem-cached-adapter/tests/StashTest.php deleted file mode 100644 index 29e142d79..000000000 --- a/vendor/league/flysystem-cached-adapter/tests/StashTest.php +++ /dev/null @@ -1,43 +0,0 @@ -shouldReceive('get')->once()->andReturn(null); - $item->shouldReceive('isMiss')->once()->andReturn(true); - $pool->shouldReceive('getItem')->once()->andReturn($item); - $cache = new Stash($pool); - $cache->load(); - $this->assertFalse($cache->isComplete('', false)); - } - - public function testLoadSuccess() - { - $response = json_encode([[], ['' => true]]); - $pool = Mockery::mock('Stash\Pool'); - $item = Mockery::mock('Stash\Item'); - $item->shouldReceive('get')->once()->andReturn($response); - $item->shouldReceive('isMiss')->once()->andReturn(false); - $pool->shouldReceive('getItem')->once()->andReturn($item); - $cache = new Stash($pool); - $cache->load(); - $this->assertTrue($cache->isComplete('', false)); - } - - public function testSave() - { - $response = json_encode([[], []]); - $pool = Mockery::mock('Stash\Pool'); - $item = Mockery::mock('Stash\Item'); - $item->shouldReceive('set')->once()->andReturn($response); - $pool->shouldReceive('getItem')->once()->andReturn($item); - $cache = new Stash($pool); - $cache->save(); - } -} diff --git a/vendor/league/flysystem/CODE_OF_CONDUCT.md b/vendor/league/flysystem/CODE_OF_CONDUCT.md deleted file mode 100644 index 89569c015..000000000 --- a/vendor/league/flysystem/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,76 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at info+flysystem@frankdejonge.nl. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq diff --git a/vendor/league/flysystem/LICENSE b/vendor/league/flysystem/LICENSE deleted file mode 100644 index f2684c841..000000000 --- a/vendor/league/flysystem/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2013-2019 Frank de Jonge - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/league/flysystem/SECURITY.md b/vendor/league/flysystem/SECURITY.md deleted file mode 100644 index f5b205ed0..000000000 --- a/vendor/league/flysystem/SECURITY.md +++ /dev/null @@ -1,16 +0,0 @@ -# Security Policy - -## Supported Versions - -| Version | Supported | -| ------- | ------------------ | -| 1.0.x | :white_check_mark: | -| 2.0.x | :x: | - -## Reporting a Vulnerability - -When you've encountered a security vulnerability, please disclose it securely. - -The security process is described at: -[https://flysystem.thephpleague.com/docs/security/](https://flysystem.thephpleague.com/docs/security/) - diff --git a/vendor/league/flysystem/composer.json b/vendor/league/flysystem/composer.json deleted file mode 100644 index 32ec81d1b..000000000 --- a/vendor/league/flysystem/composer.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "league/flysystem", - "type": "library", - "description": "Filesystem abstraction: Many filesystems, one API.", - "keywords": [ - "filesystem", "filesystems", "files", "storage", "dropbox", "aws", - "abstraction", "s3", "ftp", "sftp", "remote", "webdav", - "file systems", "cloud", "cloud files", "rackspace", "copy.com" - ], - "funding": [ - { - "type": "other", - "url": "https://offset.earth/frankdejonge" - } - ], - "license": "MIT", - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "require": { - "php": "^7.2.5 || ^8.0", - "ext-fileinfo": "*", - "league/mime-type-detection": "^1.3" - }, - "require-dev": { - "phpspec/prophecy": "^1.11.1", - "phpunit/phpunit": "^8.5.8" - }, - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "League\\Flysystem\\Stub\\": "stub/" - } - }, - "suggest": { - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" - }, - "conflict": { - "league/flysystem-sftp": "<1.0.6" - }, - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "scripts": { - "phpstan": "php phpstan.php" - } -} diff --git a/vendor/league/flysystem/deprecations.md b/vendor/league/flysystem/deprecations.md deleted file mode 100644 index c336a425d..000000000 --- a/vendor/league/flysystem/deprecations.md +++ /dev/null @@ -1,19 +0,0 @@ -# Deprecations - -This document lists all the planned deprecations. - -## Handlers will be removed in 2.0 - -The `Handler` type and associated calls will be removed in version 2.0. - -### Upgrade path - -You should create your own implementation for handling OOP usage, -but it's recommended to move away from using an OOP-style wrapper entirely. - -The reason for this is that it's too easy for implementation details (for -your application this is Flysystem) to leak into the application. The most -important part for Flysystem is that it improves portability and creates a -solid boundary between your application core and the infrastructure you use. -The OOP-style handling breaks this principle, therefore I want to stop -promoting it. diff --git a/vendor/league/flysystem/src/Adapter/AbstractAdapter.php b/vendor/league/flysystem/src/Adapter/AbstractAdapter.php deleted file mode 100644 index a6a8ed026..000000000 --- a/vendor/league/flysystem/src/Adapter/AbstractAdapter.php +++ /dev/null @@ -1,72 +0,0 @@ -pathPrefix = null; - - return; - } - - $this->pathPrefix = rtrim($prefix, '\\/') . $this->pathSeparator; - } - - /** - * Get the path prefix. - * - * @return string|null path prefix or null if pathPrefix is empty - */ - public function getPathPrefix() - { - return $this->pathPrefix; - } - - /** - * Prefix a path. - * - * @param string $path - * - * @return string prefixed path - */ - public function applyPathPrefix($path) - { - return $this->getPathPrefix() . ltrim($path, '\\/'); - } - - /** - * Remove a path prefix. - * - * @param string $path - * - * @return string path without the prefix - */ - public function removePathPrefix($path) - { - return substr($path, strlen((string) $this->getPathPrefix())); - } -} diff --git a/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php b/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php deleted file mode 100644 index 25d949ead..000000000 --- a/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php +++ /dev/null @@ -1,705 +0,0 @@ -safeStorage = new SafeStorage(); - $this->setConfig($config); - } - - /** - * Set the config. - * - * @param array $config - * - * @return $this - */ - public function setConfig(array $config) - { - foreach ($this->configurable as $setting) { - if ( ! isset($config[$setting])) { - continue; - } - - $method = 'set' . ucfirst($setting); - - if (method_exists($this, $method)) { - $this->$method($config[$setting]); - } - } - - return $this; - } - - /** - * Returns the host. - * - * @return string - */ - public function getHost() - { - return $this->host; - } - - /** - * Set the host. - * - * @param string $host - * - * @return $this - */ - public function setHost($host) - { - $this->host = $host; - - return $this; - } - - /** - * Set the public permission value. - * - * @param int $permPublic - * - * @return $this - */ - public function setPermPublic($permPublic) - { - $this->permPublic = $permPublic; - - return $this; - } - - /** - * Set the private permission value. - * - * @param int $permPrivate - * - * @return $this - */ - public function setPermPrivate($permPrivate) - { - $this->permPrivate = $permPrivate; - - return $this; - } - - /** - * Returns the ftp port. - * - * @return int - */ - public function getPort() - { - return $this->port; - } - - /** - * Returns the root folder to work from. - * - * @return string - */ - public function getRoot() - { - return $this->root; - } - - /** - * Set the ftp port. - * - * @param int|string $port - * - * @return $this - */ - public function setPort($port) - { - $this->port = (int) $port; - - return $this; - } - - /** - * Set the root folder to work from. - * - * @param string $root - * - * @return $this - */ - public function setRoot($root) - { - $this->root = rtrim($root, '\\/') . $this->separator; - - return $this; - } - - /** - * Returns the ftp username. - * - * @return string username - */ - public function getUsername() - { - $username = $this->safeStorage->retrieveSafely('username'); - - return $username !== null ? $username : 'anonymous'; - } - - /** - * Set ftp username. - * - * @param string $username - * - * @return $this - */ - public function setUsername($username) - { - $this->safeStorage->storeSafely('username', $username); - - return $this; - } - - /** - * Returns the password. - * - * @return string password - */ - public function getPassword() - { - return $this->safeStorage->retrieveSafely('password'); - } - - /** - * Set the ftp password. - * - * @param string $password - * - * @return $this - */ - public function setPassword($password) - { - $this->safeStorage->storeSafely('password', $password); - - return $this; - } - - /** - * Returns the amount of seconds before the connection will timeout. - * - * @return int - */ - public function getTimeout() - { - return $this->timeout; - } - - /** - * Set the amount of seconds before the connection should timeout. - * - * @param int $timeout - * - * @return $this - */ - public function setTimeout($timeout) - { - $this->timeout = (int) $timeout; - - return $this; - } - - /** - * Return the FTP system type. - * - * @return string - */ - public function getSystemType() - { - return $this->systemType; - } - - /** - * Set the FTP system type (windows or unix). - * - * @param string $systemType - * - * @return $this - */ - public function setSystemType($systemType) - { - $this->systemType = strtolower($systemType); - - return $this; - } - - /** - * True to enable timestamps for FTP servers that return unix-style listings. - * - * @param bool $bool - * - * @return $this - */ - public function setEnableTimestampsOnUnixListings($bool = false) - { - $this->enableTimestampsOnUnixListings = $bool; - - return $this; - } - - /** - * @inheritdoc - */ - public function listContents($directory = '', $recursive = false) - { - return $this->listDirectoryContents($directory, $recursive); - } - - abstract protected function listDirectoryContents($directory, $recursive = false); - - /** - * Normalize a directory listing. - * - * @param array $listing - * @param string $prefix - * - * @return array directory listing - */ - protected function normalizeListing(array $listing, $prefix = '') - { - $base = $prefix; - $result = []; - $listing = $this->removeDotDirectories($listing); - - while ($item = array_shift($listing)) { - if (preg_match('#^.*:$#', $item)) { - $base = preg_replace('~^\./*|:$~', '', $item); - continue; - } - - $result[] = $this->normalizeObject($item, $base); - } - - return $this->sortListing($result); - } - - /** - * Sort a directory listing. - * - * @param array $result - * - * @return array sorted listing - */ - protected function sortListing(array $result) - { - $compare = function ($one, $two) { - return strnatcmp($one['path'], $two['path']); - }; - - usort($result, $compare); - - return $result; - } - - /** - * Normalize a file entry. - * - * @param string $item - * @param string $base - * - * @return array normalized file array - * - * @throws NotSupportedException - */ - protected function normalizeObject($item, $base) - { - $systemType = $this->systemType ?: $this->detectSystemType($item); - - if ($systemType === 'unix') { - return $this->normalizeUnixObject($item, $base); - } elseif ($systemType === 'windows') { - return $this->normalizeWindowsObject($item, $base); - } - - throw NotSupportedException::forFtpSystemType($systemType); - } - - /** - * Normalize a Unix file entry. - * - * Given $item contains: - * '-rw-r--r-- 1 ftp ftp 409 Aug 19 09:01 file1.txt' - * - * This function will return: - * [ - * 'type' => 'file', - * 'path' => 'file1.txt', - * 'visibility' => 'public', - * 'size' => 409, - * 'timestamp' => 1566205260 - * ] - * - * @param string $item - * @param string $base - * - * @return array normalized file array - */ - protected function normalizeUnixObject($item, $base) - { - $item = preg_replace('#\s+#', ' ', trim($item), 7); - - if (count(explode(' ', $item, 9)) !== 9) { - throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts."); - } - - list($permissions, /* $number */, /* $owner */, /* $group */, $size, $month, $day, $timeOrYear, $name) = explode(' ', $item, 9); - $type = $this->detectType($permissions); - $path = $base === '' ? $name : $base . $this->separator . $name; - - if ($type === 'dir') { - $result = compact('type', 'path'); - if ($this->enableTimestampsOnUnixListings) { - $timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear); - $result += compact('timestamp'); - } - - return $result; - } - - $permissions = $this->normalizePermissions($permissions); - $visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE; - $size = (int) $size; - - $result = compact('type', 'path', 'visibility', 'size'); - if ($this->enableTimestampsOnUnixListings) { - $timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear); - $result += compact('timestamp'); - } - - return $result; - } - - /** - * Only accurate to the minute (current year), or to the day. - * - * Inadequacies in timestamp accuracy are due to limitations of the FTP 'LIST' command - * - * Note: The 'MLSD' command is a machine-readable replacement for 'LIST' - * but many FTP servers do not support it :( - * - * @param string $month e.g. 'Aug' - * @param string $day e.g. '19' - * @param string $timeOrYear e.g. '09:01' OR '2015' - * - * @return int - */ - protected function normalizeUnixTimestamp($month, $day, $timeOrYear) - { - if (is_numeric($timeOrYear)) { - $year = $timeOrYear; - $hour = '00'; - $minute = '00'; - $seconds = '00'; - } else { - $year = date('Y'); - list($hour, $minute) = explode(':', $timeOrYear); - $seconds = '00'; - } - $dateTime = DateTime::createFromFormat('Y-M-j-G:i:s', "{$year}-{$month}-{$day}-{$hour}:{$minute}:{$seconds}"); - - return $dateTime->getTimestamp(); - } - - /** - * Normalize a Windows/DOS file entry. - * - * @param string $item - * @param string $base - * - * @return array normalized file array - */ - protected function normalizeWindowsObject($item, $base) - { - $item = preg_replace('#\s+#', ' ', trim($item), 3); - - if (count(explode(' ', $item, 4)) !== 4) { - throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts."); - } - - list($date, $time, $size, $name) = explode(' ', $item, 4); - $path = $base === '' ? $name : $base . $this->separator . $name; - - // Check for the correct date/time format - $format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i'; - $dt = DateTime::createFromFormat($format, $date . $time); - $timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time"); - - if ($size === '') { - $type = 'dir'; - - return compact('type', 'path', 'timestamp'); - } - - $type = 'file'; - $visibility = AdapterInterface::VISIBILITY_PUBLIC; - $size = (int) $size; - - return compact('type', 'path', 'visibility', 'size', 'timestamp'); - } - - /** - * Get the system type from a listing item. - * - * @param string $item - * - * @return string the system type - */ - protected function detectSystemType($item) - { - return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', trim($item)) ? 'windows' : 'unix'; - } - - /** - * Get the file type from the permissions. - * - * @param string $permissions - * - * @return string file type - */ - protected function detectType($permissions) - { - return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file'; - } - - /** - * Normalize a permissions string. - * - * @param string $permissions - * - * @return int - */ - protected function normalizePermissions($permissions) - { - if (is_numeric($permissions)) { - return ((int) $permissions) & 0777; - } - - // remove the type identifier - $permissions = substr($permissions, 1); - - // map the string rights to the numeric counterparts - $map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1']; - $permissions = strtr($permissions, $map); - - // split up the permission groups - $parts = str_split($permissions, 3); - - // convert the groups - $mapper = function ($part) { - return array_sum(str_split($part)); - }; - - // converts to decimal number - return octdec(implode('', array_map($mapper, $parts))); - } - - /** - * Filter out dot-directories. - * - * @param array $list - * - * @return array - */ - public function removeDotDirectories(array $list) - { - $filter = function ($line) { - return $line !== '' && ! preg_match('#.* \.(\.)?$|^total#', $line); - }; - - return array_filter($list, $filter); - } - - /** - * @inheritdoc - */ - public function has($path) - { - return $this->getMetadata($path); - } - - /** - * @inheritdoc - */ - public function getSize($path) - { - return $this->getMetadata($path); - } - - /** - * @inheritdoc - */ - public function getVisibility($path) - { - return $this->getMetadata($path); - } - - /** - * Ensure a directory exists. - * - * @param string $dirname - */ - public function ensureDirectory($dirname) - { - $dirname = (string) $dirname; - - if ($dirname !== '' && ! $this->has($dirname)) { - $this->createDir($dirname, new Config()); - } - } - - /** - * @return mixed - */ - public function getConnection() - { - if ( ! $this->isConnected()) { - $this->disconnect(); - $this->connect(); - } - - return $this->connection; - } - - /** - * Get the public permission value. - * - * @return int - */ - public function getPermPublic() - { - return $this->permPublic; - } - - /** - * Get the private permission value. - * - * @return int - */ - public function getPermPrivate() - { - return $this->permPrivate; - } - - /** - * Disconnect on destruction. - */ - public function __destruct() - { - $this->disconnect(); - } - - /** - * Establish a connection. - */ - abstract public function connect(); - - /** - * Close the connection. - */ - abstract public function disconnect(); - - /** - * Check if a connection is active. - * - * @return bool - */ - abstract public function isConnected(); - - protected function escapePath($path) - { - return str_replace(['*', '[', ']'], ['\\*', '\\[', '\\]'], $path); - } -} diff --git a/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php b/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php deleted file mode 100644 index fd8d2161e..000000000 --- a/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php +++ /dev/null @@ -1,12 +0,0 @@ -transferMode = $mode; - - return $this; - } - - /** - * Set if Ssl is enabled. - * - * @param bool $ssl - * - * @return $this - */ - public function setSsl($ssl) - { - $this->ssl = (bool) $ssl; - - return $this; - } - - /** - * Set if passive mode should be used. - * - * @param bool $passive - */ - public function setPassive($passive = true) - { - $this->passive = $passive; - } - - /** - * @param bool $ignorePassiveAddress - */ - public function setIgnorePassiveAddress($ignorePassiveAddress) - { - $this->ignorePassiveAddress = $ignorePassiveAddress; - } - - /** - * @param bool $recurseManually - */ - public function setRecurseManually($recurseManually) - { - $this->recurseManually = $recurseManually; - } - - /** - * @param bool $utf8 - */ - public function setUtf8($utf8) - { - $this->utf8 = (bool) $utf8; - } - - /** - * Connect to the FTP server. - */ - public function connect() - { - $tries = 3; - start_connecting: - - if ($this->ssl) { - $this->connection = @ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout()); - } else { - $this->connection = @ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout()); - } - - if ( ! $this->connection) { - $tries--; - - if ($tries > 0) goto start_connecting; - - throw new ConnectionRuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort()); - } - - $this->login(); - $this->setUtf8Mode(); - $this->setConnectionPassiveMode(); - $this->setConnectionRoot(); - $this->isPureFtpd = $this->isPureFtpdServer(); - } - - /** - * Set the connection to UTF-8 mode. - */ - protected function setUtf8Mode() - { - if ($this->utf8) { - $response = ftp_raw($this->connection, "OPTS UTF8 ON"); - if (!in_array(substr($response[0], 0, 3), ['200', '202'])) { - throw new ConnectionRuntimeException( - 'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort() - ); - } - } - } - - /** - * Set the connections to passive mode. - * - * @throws ConnectionRuntimeException - */ - protected function setConnectionPassiveMode() - { - if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) { - ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress); - } - - if ( ! ftp_pasv($this->connection, $this->passive)) { - throw new ConnectionRuntimeException( - 'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort() - ); - } - } - - /** - * Set the connection root. - */ - protected function setConnectionRoot() - { - $root = $this->getRoot(); - $connection = $this->connection; - - if ($root && ! ftp_chdir($connection, $root)) { - throw new InvalidRootException('Root is invalid or does not exist: ' . $this->getRoot()); - } - - // Store absolute path for further reference. - // This is needed when creating directories and - // initial root was a relative path, else the root - // would be relative to the chdir'd path. - $this->root = ftp_pwd($connection); - } - - /** - * Login. - * - * @throws ConnectionRuntimeException - */ - protected function login() - { - set_error_handler(function () { - }); - $isLoggedIn = ftp_login( - $this->connection, - $this->getUsername(), - $this->getPassword() - ); - restore_error_handler(); - - if ( ! $isLoggedIn) { - $this->disconnect(); - throw new ConnectionRuntimeException( - 'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort( - ) . ', username: ' . $this->getUsername() - ); - } - } - - /** - * Disconnect from the FTP server. - */ - public function disconnect() - { - if ($this->hasFtpConnection()) { - @ftp_close($this->connection); - } - - $this->connection = null; - } - - /** - * @inheritdoc - */ - public function write($path, $contents, Config $config) - { - $stream = fopen('php://temp', 'w+b'); - fwrite($stream, $contents); - rewind($stream); - $result = $this->writeStream($path, $stream, $config); - fclose($stream); - - if ($result === false) { - return false; - } - - $result['contents'] = $contents; - $result['mimetype'] = $config->get('mimetype') ?: Util::guessMimeType($path, $contents); - - return $result; - } - - /** - * @inheritdoc - */ - public function writeStream($path, $resource, Config $config) - { - $this->ensureDirectory(Util::dirname($path)); - - if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) { - return false; - } - - if ($visibility = $config->get('visibility')) { - $this->setVisibility($path, $visibility); - } - - $type = 'file'; - - return compact('type', 'path', 'visibility'); - } - - /** - * @inheritdoc - */ - public function update($path, $contents, Config $config) - { - return $this->write($path, $contents, $config); - } - - /** - * @inheritdoc - */ - public function updateStream($path, $resource, Config $config) - { - return $this->writeStream($path, $resource, $config); - } - - /** - * @inheritdoc - */ - public function rename($path, $newpath) - { - return ftp_rename($this->getConnection(), $path, $newpath); - } - - /** - * @inheritdoc - */ - public function delete($path) - { - return ftp_delete($this->getConnection(), $path); - } - - /** - * @inheritdoc - */ - public function deleteDir($dirname) - { - $connection = $this->getConnection(); - $contents = array_reverse($this->listDirectoryContents($dirname, false)); - - foreach ($contents as $object) { - if ($object['type'] === 'file') { - if ( ! ftp_delete($connection, $object['path'])) { - return false; - } - } elseif ( ! $this->deleteDir($object['path'])) { - return false; - } - } - - return ftp_rmdir($connection, $dirname); - } - - /** - * @inheritdoc - */ - public function createDir($dirname, Config $config) - { - $connection = $this->getConnection(); - $directories = explode('/', $dirname); - - foreach ($directories as $directory) { - if (false === $this->createActualDirectory($directory, $connection)) { - $this->setConnectionRoot(); - - return false; - } - - ftp_chdir($connection, $directory); - } - - $this->setConnectionRoot(); - - return ['type' => 'dir', 'path' => $dirname]; - } - - /** - * Create a directory. - * - * @param string $directory - * @param resource $connection - * - * @return bool - */ - protected function createActualDirectory($directory, $connection) - { - // List the current directory - $listing = ftp_nlist($connection, '.') ?: []; - - foreach ($listing as $key => $item) { - if (preg_match('~^\./.*~', $item)) { - $listing[$key] = substr($item, 2); - } - } - - if (in_array($directory, $listing, true)) { - return true; - } - - return (boolean) ftp_mkdir($connection, $directory); - } - - /** - * @inheritdoc - */ - public function getMetadata($path) - { - if ($path === '') { - return ['type' => 'dir', 'path' => '']; - } - - if (@ftp_chdir($this->getConnection(), $path) === true) { - $this->setConnectionRoot(); - - return ['type' => 'dir', 'path' => $path]; - } - - $listing = $this->ftpRawlist('-A', $path); - - if (empty($listing) || in_array('total 0', $listing, true)) { - return false; - } - - if (preg_match('/.* not found/', $listing[0])) { - return false; - } - - if (preg_match('/^total [0-9]*$/', $listing[0])) { - array_shift($listing); - } - - return $this->normalizeObject($listing[0], ''); - } - - /** - * @inheritdoc - */ - public function getMimetype($path) - { - if ( ! $metadata = $this->getMetadata($path)) { - return false; - } - - $metadata['mimetype'] = MimeType::detectByFilename($path); - - return $metadata; - } - - /** - * @inheritdoc - */ - public function getTimestamp($path) - { - $timestamp = ftp_mdtm($this->getConnection(), $path); - - return ($timestamp !== -1) ? ['path' => $path, 'timestamp' => $timestamp] : false; - } - - /** - * @inheritdoc - */ - public function read($path) - { - if ( ! $object = $this->readStream($path)) { - return false; - } - - $object['contents'] = stream_get_contents($object['stream']); - fclose($object['stream']); - unset($object['stream']); - - return $object; - } - - /** - * @inheritdoc - */ - public function readStream($path) - { - $stream = fopen('php://temp', 'w+b'); - $result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode); - rewind($stream); - - if ( ! $result) { - fclose($stream); - - return false; - } - - return ['type' => 'file', 'path' => $path, 'stream' => $stream]; - } - - /** - * @inheritdoc - */ - public function setVisibility($path, $visibility) - { - $mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate(); - - if ( ! ftp_chmod($this->getConnection(), $mode, $path)) { - return false; - } - - return compact('path', 'visibility'); - } - - /** - * @inheritdoc - * - * @param string $directory - */ - protected function listDirectoryContents($directory, $recursive = true) - { - if ($recursive && $this->recurseManually) { - return $this->listDirectoryContentsRecursive($directory); - } - - $options = $recursive ? '-alnR' : '-aln'; - $listing = $this->ftpRawlist($options, $directory); - - return $listing ? $this->normalizeListing($listing, $directory) : []; - } - - /** - * @inheritdoc - * - * @param string $directory - */ - protected function listDirectoryContentsRecursive($directory) - { - $listing = $this->normalizeListing($this->ftpRawlist('-aln', $directory) ?: [], $directory); - $output = []; - - foreach ($listing as $item) { - $output[] = $item; - if ($item['type'] !== 'dir') { - continue; - } - $output = array_merge($output, $this->listDirectoryContentsRecursive($item['path'])); - } - - return $output; - } - - /** - * Check if the connection is open. - * - * @return bool - * - * @throws ConnectionErrorException - */ - public function isConnected() - { - return $this->hasFtpConnection() && $this->getRawExecResponseCode('NOOP') === 200; - } - - /** - * @return bool - */ - protected function isPureFtpdServer() - { - $response = ftp_raw($this->connection, 'HELP'); - - return stripos(implode(' ', $response), 'Pure-FTPd') !== false; - } - - /** - * The ftp_rawlist function with optional escaping. - * - * @param string $options - * @param string $path - * - * @return array - */ - protected function ftpRawlist($options, $path) - { - $connection = $this->getConnection(); - - if ($this->isPureFtpd) { - $path = str_replace([' ', '[', ']'], ['\ ', '\\[', '\\]'], $path); - } - - return ftp_rawlist($connection, $options . ' ' . $this->escapePath($path)); - } - - private function getRawExecResponseCode($command) - { - $response = @ftp_raw($this->connection, trim($command)); - - return (int) preg_replace('/\D/', '', implode(' ', $response)); - } - - private function hasFtpConnection(): bool - { - return is_resource($this->connection) || $this->connection instanceof \FTP\Connection; - } -} diff --git a/vendor/league/flysystem/src/Adapter/Ftpd.php b/vendor/league/flysystem/src/Adapter/Ftpd.php deleted file mode 100644 index 7e71d19f6..000000000 --- a/vendor/league/flysystem/src/Adapter/Ftpd.php +++ /dev/null @@ -1,48 +0,0 @@ - 'dir', 'path' => '']; - } - - if (@ftp_chdir($this->getConnection(), $path) === true) { - $this->setConnectionRoot(); - - return ['type' => 'dir', 'path' => $path]; - } - - $object = ftp_raw($this->getConnection(), 'STAT ' . $this->escapePath($path)); - - if ( ! $object || count($object) < 3) { - return false; - } - - if (substr($object[1], 0, 5) === "ftpd:") { - return false; - } - - return $this->normalizeObject($object[1], ''); - } - - /** - * @inheritdoc - */ - protected function listDirectoryContents($directory, $recursive = true) - { - $listing = ftp_rawlist($this->getConnection(), $this->escapePath($directory), $recursive); - - if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) { - return []; - } - - return $this->normalizeListing($listing, $directory); - } -} diff --git a/vendor/league/flysystem/src/Adapter/Local.php b/vendor/league/flysystem/src/Adapter/Local.php deleted file mode 100644 index 747c463ec..000000000 --- a/vendor/league/flysystem/src/Adapter/Local.php +++ /dev/null @@ -1,533 +0,0 @@ - [ - 'public' => 0644, - 'private' => 0600, - ], - 'dir' => [ - 'public' => 0755, - 'private' => 0700, - ], - ]; - - /** - * @var string - */ - protected $pathSeparator = DIRECTORY_SEPARATOR; - - /** - * @var array - */ - protected $permissionMap; - - /** - * @var int - */ - protected $writeFlags; - - /** - * @var int - */ - private $linkHandling; - - /** - * Constructor. - * - * @param string $root - * @param int $writeFlags - * @param int $linkHandling - * @param array $permissions - * - * @throws LogicException - */ - public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = []) - { - $root = is_link($root) ? realpath($root) : $root; - $this->permissionMap = array_replace_recursive(static::$permissions, $permissions); - $this->ensureDirectory($root); - - if ( ! is_dir($root) || ! is_readable($root)) { - throw new LogicException('The root path ' . $root . ' is not readable.'); - } - - $this->setPathPrefix($root); - $this->writeFlags = $writeFlags; - $this->linkHandling = $linkHandling; - } - - /** - * Ensure the root directory exists. - * - * @param string $root root directory path - * - * @return void - * - * @throws Exception in case the root directory can not be created - */ - protected function ensureDirectory($root) - { - if ( ! is_dir($root)) { - $umask = umask(0); - - if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) { - $mkdirError = error_get_last(); - } - - umask($umask); - clearstatcache(false, $root); - - if ( ! is_dir($root)) { - $errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : ''; - throw new Exception(sprintf('Impossible to create the root directory "%s". %s', $root, $errorMessage)); - } - } - } - - /** - * @inheritdoc - */ - public function has($path) - { - $location = $this->applyPathPrefix($path); - - return file_exists($location); - } - - /** - * @inheritdoc - */ - public function write($path, $contents, Config $config) - { - $location = $this->applyPathPrefix($path); - $this->ensureDirectory(dirname($location)); - - if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) { - return false; - } - - $type = 'file'; - $result = compact('contents', 'type', 'size', 'path'); - - if ($visibility = $config->get('visibility')) { - $result['visibility'] = $visibility; - $this->setVisibility($path, $visibility); - } - - return $result; - } - - /** - * @inheritdoc - */ - public function writeStream($path, $resource, Config $config) - { - $location = $this->applyPathPrefix($path); - $this->ensureDirectory(dirname($location)); - $stream = fopen($location, 'w+b'); - - if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) { - return false; - } - - $type = 'file'; - $result = compact('type', 'path'); - - if ($visibility = $config->get('visibility')) { - $this->setVisibility($path, $visibility); - $result['visibility'] = $visibility; - } - - return $result; - } - - /** - * @inheritdoc - */ - public function readStream($path) - { - $location = $this->applyPathPrefix($path); - $stream = fopen($location, 'rb'); - - return ['type' => 'file', 'path' => $path, 'stream' => $stream]; - } - - /** - * @inheritdoc - */ - public function updateStream($path, $resource, Config $config) - { - return $this->writeStream($path, $resource, $config); - } - - /** - * @inheritdoc - */ - public function update($path, $contents, Config $config) - { - $location = $this->applyPathPrefix($path); - $size = file_put_contents($location, $contents, $this->writeFlags); - - if ($size === false) { - return false; - } - - $type = 'file'; - - $result = compact('type', 'path', 'size', 'contents'); - - if ($visibility = $config->get('visibility')) { - $this->setVisibility($path, $visibility); - $result['visibility'] = $visibility; - } - - return $result; - } - - /** - * @inheritdoc - */ - public function read($path) - { - $location = $this->applyPathPrefix($path); - $contents = @file_get_contents($location); - - if ($contents === false) { - return false; - } - - return ['type' => 'file', 'path' => $path, 'contents' => $contents]; - } - - /** - * @inheritdoc - */ - public function rename($path, $newpath) - { - $location = $this->applyPathPrefix($path); - $destination = $this->applyPathPrefix($newpath); - $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath)); - $this->ensureDirectory($parentDirectory); - - return rename($location, $destination); - } - - /** - * @inheritdoc - */ - public function copy($path, $newpath) - { - $location = $this->applyPathPrefix($path); - $destination = $this->applyPathPrefix($newpath); - $this->ensureDirectory(dirname($destination)); - - return copy($location, $destination); - } - - /** - * @inheritdoc - */ - public function delete($path) - { - $location = $this->applyPathPrefix($path); - - return @unlink($location); - } - - /** - * @inheritdoc - */ - public function listContents($directory = '', $recursive = false) - { - $result = []; - $location = $this->applyPathPrefix($directory); - - if ( ! is_dir($location)) { - return []; - } - - $iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location); - - foreach ($iterator as $file) { - $path = $this->getFilePath($file); - - if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) { - continue; - } - - $result[] = $this->normalizeFileInfo($file); - } - - unset($iterator); - - return array_filter($result); - } - - /** - * @inheritdoc - */ - public function getMetadata($path) - { - $location = $this->applyPathPrefix($path); - clearstatcache(false, $location); - $info = new SplFileInfo($location); - - return $this->normalizeFileInfo($info); - } - - /** - * @inheritdoc - */ - public function getSize($path) - { - return $this->getMetadata($path); - } - - /** - * @inheritdoc - */ - public function getMimetype($path) - { - $location = $this->applyPathPrefix($path); - $finfo = new Finfo(FILEINFO_MIME_TYPE); - $mimetype = $finfo->file($location); - - if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty', 'application/x-empty'])) { - $mimetype = Util\MimeType::detectByFilename($location); - } - - return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype]; - } - - /** - * @inheritdoc - */ - public function getTimestamp($path) - { - return $this->getMetadata($path); - } - - /** - * @inheritdoc - */ - public function getVisibility($path) - { - $location = $this->applyPathPrefix($path); - clearstatcache(false, $location); - $permissions = octdec(substr(sprintf('%o', fileperms($location)), -4)); - $type = is_dir($location) ? 'dir' : 'file'; - - foreach ($this->permissionMap[$type] as $visibility => $visibilityPermissions) { - if ($visibilityPermissions == $permissions) { - return compact('path', 'visibility'); - } - } - - $visibility = substr(sprintf('%o', fileperms($location)), -4); - - return compact('path', 'visibility'); - } - - /** - * @inheritdoc - */ - public function setVisibility($path, $visibility) - { - $location = $this->applyPathPrefix($path); - $type = is_dir($location) ? 'dir' : 'file'; - $success = chmod($location, $this->permissionMap[$type][$visibility]); - - if ($success === false) { - return false; - } - - return compact('path', 'visibility'); - } - - /** - * @inheritdoc - */ - public function createDir($dirname, Config $config) - { - $location = $this->applyPathPrefix($dirname); - $umask = umask(0); - $visibility = $config->get('visibility', 'public'); - $return = ['path' => $dirname, 'type' => 'dir']; - - if ( ! is_dir($location)) { - if (false === @mkdir($location, $this->permissionMap['dir'][$visibility], true) - || false === is_dir($location)) { - $return = false; - } - } - - umask($umask); - - return $return; - } - - /** - * @inheritdoc - */ - public function deleteDir($dirname) - { - $location = $this->applyPathPrefix($dirname); - - if ( ! is_dir($location)) { - return false; - } - - $contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST); - - /** @var SplFileInfo $file */ - foreach ($contents as $file) { - $this->guardAgainstUnreadableFileInfo($file); - $this->deleteFileInfoObject($file); - } - - unset($contents); - - return rmdir($location); - } - - /** - * @param SplFileInfo $file - */ - protected function deleteFileInfoObject(SplFileInfo $file) - { - switch ($file->getType()) { - case 'dir': - rmdir($file->getRealPath()); - break; - case 'link': - unlink($file->getPathname()); - break; - default: - unlink($file->getRealPath()); - } - } - - /** - * Normalize the file info. - * - * @param SplFileInfo $file - * - * @return array|void - * - * @throws NotSupportedException - */ - protected function normalizeFileInfo(SplFileInfo $file) - { - if ( ! $file->isLink()) { - return $this->mapFileInfo($file); - } - - if ($this->linkHandling & self::DISALLOW_LINKS) { - throw NotSupportedException::forLink($file); - } - } - - /** - * Get the normalized path from a SplFileInfo object. - * - * @param SplFileInfo $file - * - * @return string - */ - protected function getFilePath(SplFileInfo $file) - { - $location = $file->getPathname(); - $path = $this->removePathPrefix($location); - - return trim(str_replace('\\', '/', $path), '/'); - } - - /** - * @param string $path - * @param int $mode - * - * @return RecursiveIteratorIterator - */ - protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST) - { - return new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), - $mode - ); - } - - /** - * @param string $path - * - * @return DirectoryIterator - */ - protected function getDirectoryIterator($path) - { - $iterator = new DirectoryIterator($path); - - return $iterator; - } - - /** - * @param SplFileInfo $file - * - * @return array - */ - protected function mapFileInfo(SplFileInfo $file) - { - $normalized = [ - 'type' => $file->getType(), - 'path' => $this->getFilePath($file), - ]; - - $normalized['timestamp'] = $file->getMTime(); - - if ($normalized['type'] === 'file') { - $normalized['size'] = $file->getSize(); - } - - return $normalized; - } - - /** - * @param SplFileInfo $file - * - * @throws UnreadableFileException - */ - protected function guardAgainstUnreadableFileInfo(SplFileInfo $file) - { - if ( ! $file->isReadable()) { - throw UnreadableFileException::forFileInfo($file); - } - } -} diff --git a/vendor/league/flysystem/src/Adapter/NullAdapter.php b/vendor/league/flysystem/src/Adapter/NullAdapter.php deleted file mode 100644 index 2527087f7..000000000 --- a/vendor/league/flysystem/src/Adapter/NullAdapter.php +++ /dev/null @@ -1,144 +0,0 @@ -get('visibility')) { - $result['visibility'] = $visibility; - } - - return $result; - } - - /** - * @inheritdoc - */ - public function update($path, $contents, Config $config) - { - return false; - } - - /** - * @inheritdoc - */ - public function read($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function rename($path, $newpath) - { - return false; - } - - /** - * @inheritdoc - */ - public function delete($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function listContents($directory = '', $recursive = false) - { - return []; - } - - /** - * @inheritdoc - */ - public function getMetadata($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function getSize($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function getMimetype($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function getTimestamp($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function getVisibility($path) - { - return false; - } - - /** - * @inheritdoc - */ - public function setVisibility($path, $visibility) - { - return compact('visibility'); - } - - /** - * @inheritdoc - */ - public function createDir($dirname, Config $config) - { - return ['path' => $dirname, 'type' => 'dir']; - } - - /** - * @inheritdoc - */ - public function deleteDir($dirname) - { - return false; - } -} diff --git a/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php b/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php deleted file mode 100644 index fc0a747ac..000000000 --- a/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php +++ /dev/null @@ -1,33 +0,0 @@ -readStream($path); - - if ($response === false || ! is_resource($response['stream'])) { - return false; - } - - $result = $this->writeStream($newpath, $response['stream'], new Config()); - - if ($result !== false && is_resource($response['stream'])) { - fclose($response['stream']); - } - - return $result !== false; - } - - // Required abstract method - - /** - * @param string $path - * - * @return resource - */ - abstract public function readStream($path); - - /** - * @param string $path - * @param resource $resource - * @param Config $config - * - * @return resource - */ - abstract public function writeStream($path, $resource, Config $config); -} diff --git a/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php b/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php deleted file mode 100644 index 2b31c01d6..000000000 --- a/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php +++ /dev/null @@ -1,44 +0,0 @@ -read($path)) { - return false; - } - - $stream = fopen('php://temp', 'w+b'); - fwrite($stream, $data['contents']); - rewind($stream); - $data['stream'] = $stream; - unset($data['contents']); - - return $data; - } - - /** - * Reads a file. - * - * @param string $path - * - * @return array|false - * - * @see League\Flysystem\ReadInterface::read() - */ - abstract public function read($path); -} diff --git a/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php b/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php deleted file mode 100644 index 80424960c..000000000 --- a/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php +++ /dev/null @@ -1,9 +0,0 @@ -stream($path, $resource, $config, 'write'); - } - - /** - * Update a file using a stream. - * - * @param string $path - * @param resource $resource - * @param Config $config Config object or visibility setting - * - * @return mixed false of file metadata - */ - public function updateStream($path, $resource, Config $config) - { - return $this->stream($path, $resource, $config, 'update'); - } - - // Required abstract methods - abstract public function write($pash, $contents, Config $config); - abstract public function update($pash, $contents, Config $config); -} diff --git a/vendor/league/flysystem/src/Adapter/SynologyFtp.php b/vendor/league/flysystem/src/Adapter/SynologyFtp.php deleted file mode 100644 index fe0d344cf..000000000 --- a/vendor/league/flysystem/src/Adapter/SynologyFtp.php +++ /dev/null @@ -1,8 +0,0 @@ -settings = $settings; - } - - /** - * Get a setting. - * - * @param string $key - * @param mixed $default - * - * @return mixed config setting or default when not found - */ - public function get($key, $default = null) - { - if ( ! array_key_exists($key, $this->settings)) { - return $this->getDefault($key, $default); - } - - return $this->settings[$key]; - } - - /** - * Check if an item exists by key. - * - * @param string $key - * - * @return bool - */ - public function has($key) - { - if (array_key_exists($key, $this->settings)) { - return true; - } - - return $this->fallback instanceof Config - ? $this->fallback->has($key) - : false; - } - - /** - * Try to retrieve a default setting from a config fallback. - * - * @param string $key - * @param mixed $default - * - * @return mixed config setting or default when not found - */ - protected function getDefault($key, $default) - { - if ( ! $this->fallback) { - return $default; - } - - return $this->fallback->get($key, $default); - } - - /** - * Set a setting. - * - * @param string $key - * @param mixed $value - * - * @return $this - */ - public function set($key, $value) - { - $this->settings[$key] = $value; - - return $this; - } - - /** - * Set the fallback. - * - * @param Config $fallback - * - * @return $this - */ - public function setFallback(Config $fallback) - { - $this->fallback = $fallback; - - return $this; - } -} diff --git a/vendor/league/flysystem/src/ConfigAwareTrait.php b/vendor/league/flysystem/src/ConfigAwareTrait.php deleted file mode 100644 index 202d605da..000000000 --- a/vendor/league/flysystem/src/ConfigAwareTrait.php +++ /dev/null @@ -1,49 +0,0 @@ -config = $config ? Util::ensureConfig($config) : new Config; - } - - /** - * Get the Config. - * - * @return Config config object - */ - public function getConfig() - { - return $this->config; - } - - /** - * Convert a config array to a Config object with the correct fallback. - * - * @param array $config - * - * @return Config - */ - protected function prepareConfig(array $config) - { - $config = new Config($config); - $config->setFallback($this->getConfig()); - - return $config; - } -} diff --git a/vendor/league/flysystem/src/ConnectionErrorException.php b/vendor/league/flysystem/src/ConnectionErrorException.php deleted file mode 100644 index adb651d3d..000000000 --- a/vendor/league/flysystem/src/ConnectionErrorException.php +++ /dev/null @@ -1,9 +0,0 @@ -filesystem->deleteDir($this->path); - } - - /** - * List the directory contents. - * - * @param bool $recursive - * - * @return array|bool directory contents or false - */ - public function getContents($recursive = false) - { - return $this->filesystem->listContents($this->path, $recursive); - } -} diff --git a/vendor/league/flysystem/src/Exception.php b/vendor/league/flysystem/src/Exception.php deleted file mode 100644 index 4596c0a9a..000000000 --- a/vendor/league/flysystem/src/Exception.php +++ /dev/null @@ -1,8 +0,0 @@ -filesystem->has($this->path); - } - - /** - * Read the file. - * - * @return string|false file contents - */ - public function read() - { - return $this->filesystem->read($this->path); - } - - /** - * Read the file as a stream. - * - * @return resource|false file stream - */ - public function readStream() - { - return $this->filesystem->readStream($this->path); - } - - /** - * Write the new file. - * - * @param string $content - * - * @return bool success boolean - */ - public function write($content) - { - return $this->filesystem->write($this->path, $content); - } - - /** - * Write the new file using a stream. - * - * @param resource $resource - * - * @return bool success boolean - */ - public function writeStream($resource) - { - return $this->filesystem->writeStream($this->path, $resource); - } - - /** - * Update the file contents. - * - * @param string $content - * - * @return bool success boolean - */ - public function update($content) - { - return $this->filesystem->update($this->path, $content); - } - - /** - * Update the file contents with a stream. - * - * @param resource $resource - * - * @return bool success boolean - */ - public function updateStream($resource) - { - return $this->filesystem->updateStream($this->path, $resource); - } - - /** - * Create the file or update if exists. - * - * @param string $content - * - * @return bool success boolean - */ - public function put($content) - { - return $this->filesystem->put($this->path, $content); - } - - /** - * Create the file or update if exists using a stream. - * - * @param resource $resource - * - * @return bool success boolean - */ - public function putStream($resource) - { - return $this->filesystem->putStream($this->path, $resource); - } - - /** - * Rename the file. - * - * @param string $newpath - * - * @return bool success boolean - */ - public function rename($newpath) - { - if ($this->filesystem->rename($this->path, $newpath)) { - $this->path = $newpath; - - return true; - } - - return false; - } - - /** - * Copy the file. - * - * @param string $newpath - * - * @return File|false new file or false - */ - public function copy($newpath) - { - if ($this->filesystem->copy($this->path, $newpath)) { - return new File($this->filesystem, $newpath); - } - - return false; - } - - /** - * Get the file's timestamp. - * - * @return string|false The timestamp or false on failure. - */ - public function getTimestamp() - { - return $this->filesystem->getTimestamp($this->path); - } - - /** - * Get the file's mimetype. - * - * @return string|false The file mime-type or false on failure. - */ - public function getMimetype() - { - return $this->filesystem->getMimetype($this->path); - } - - /** - * Get the file's visibility. - * - * @return string|false The visibility (public|private) or false on failure. - */ - public function getVisibility() - { - return $this->filesystem->getVisibility($this->path); - } - - /** - * Get the file's metadata. - * - * @return array|false The file metadata or false on failure. - */ - public function getMetadata() - { - return $this->filesystem->getMetadata($this->path); - } - - /** - * Get the file size. - * - * @return int|false The file size or false on failure. - */ - public function getSize() - { - return $this->filesystem->getSize($this->path); - } - - /** - * Delete the file. - * - * @return bool success boolean - */ - public function delete() - { - return $this->filesystem->delete($this->path); - } -} diff --git a/vendor/league/flysystem/src/FileExistsException.php b/vendor/league/flysystem/src/FileExistsException.php deleted file mode 100644 index c82e20c16..000000000 --- a/vendor/league/flysystem/src/FileExistsException.php +++ /dev/null @@ -1,37 +0,0 @@ -path = $path; - - parent::__construct('File already exists at path: ' . $this->getPath(), $code, $previous); - } - - /** - * Get the path which was found. - * - * @return string - */ - public function getPath() - { - return $this->path; - } -} diff --git a/vendor/league/flysystem/src/FileNotFoundException.php b/vendor/league/flysystem/src/FileNotFoundException.php deleted file mode 100644 index 989df69bb..000000000 --- a/vendor/league/flysystem/src/FileNotFoundException.php +++ /dev/null @@ -1,37 +0,0 @@ -path = $path; - - parent::__construct('File not found at path: ' . $this->getPath(), $code, $previous); - } - - /** - * Get the path which was not found. - * - * @return string - */ - public function getPath() - { - return $this->path; - } -} diff --git a/vendor/league/flysystem/src/Filesystem.php b/vendor/league/flysystem/src/Filesystem.php deleted file mode 100644 index c4eaf2781..000000000 --- a/vendor/league/flysystem/src/Filesystem.php +++ /dev/null @@ -1,409 +0,0 @@ -adapter = $adapter; - $this->setConfig($config); - } - - /** - * Get the Adapter. - * - * @return AdapterInterface adapter - */ - public function getAdapter() - { - return $this->adapter; - } - - /** - * @inheritdoc - */ - public function has($path) - { - $path = Util::normalizePath($path); - - return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path); - } - - /** - * @inheritdoc - */ - public function write($path, $contents, array $config = []) - { - $path = Util::normalizePath($path); - $this->assertAbsent($path); - $config = $this->prepareConfig($config); - - return (bool) $this->getAdapter()->write($path, $contents, $config); - } - - /** - * @inheritdoc - */ - public function writeStream($path, $resource, array $config = []) - { - if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') { - throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); - } - - $path = Util::normalizePath($path); - $this->assertAbsent($path); - $config = $this->prepareConfig($config); - - Util::rewindStream($resource); - - return (bool) $this->getAdapter()->writeStream($path, $resource, $config); - } - - /** - * @inheritdoc - */ - public function put($path, $contents, array $config = []) - { - $path = Util::normalizePath($path); - $config = $this->prepareConfig($config); - - if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) { - return (bool) $this->getAdapter()->update($path, $contents, $config); - } - - return (bool) $this->getAdapter()->write($path, $contents, $config); - } - - /** - * @inheritdoc - */ - public function putStream($path, $resource, array $config = []) - { - if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') { - throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); - } - - $path = Util::normalizePath($path); - $config = $this->prepareConfig($config); - Util::rewindStream($resource); - - if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) { - return (bool) $this->getAdapter()->updateStream($path, $resource, $config); - } - - return (bool) $this->getAdapter()->writeStream($path, $resource, $config); - } - - /** - * @inheritdoc - */ - public function readAndDelete($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - $contents = $this->read($path); - - if ($contents === false) { - return false; - } - - $this->delete($path); - - return $contents; - } - - /** - * @inheritdoc - */ - public function update($path, $contents, array $config = []) - { - $path = Util::normalizePath($path); - $config = $this->prepareConfig($config); - - $this->assertPresent($path); - - return (bool) $this->getAdapter()->update($path, $contents, $config); - } - - /** - * @inheritdoc - */ - public function updateStream($path, $resource, array $config = []) - { - if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') { - throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); - } - - $path = Util::normalizePath($path); - $config = $this->prepareConfig($config); - $this->assertPresent($path); - Util::rewindStream($resource); - - return (bool) $this->getAdapter()->updateStream($path, $resource, $config); - } - - /** - * @inheritdoc - */ - public function read($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - if ( ! ($object = $this->getAdapter()->read($path))) { - return false; - } - - return $object['contents']; - } - - /** - * @inheritdoc - */ - public function readStream($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - if ( ! $object = $this->getAdapter()->readStream($path)) { - return false; - } - - return $object['stream']; - } - - /** - * @inheritdoc - */ - public function rename($path, $newpath) - { - $path = Util::normalizePath($path); - $newpath = Util::normalizePath($newpath); - $this->assertPresent($path); - $this->assertAbsent($newpath); - - return (bool) $this->getAdapter()->rename($path, $newpath); - } - - /** - * @inheritdoc - */ - public function copy($path, $newpath) - { - $path = Util::normalizePath($path); - $newpath = Util::normalizePath($newpath); - $this->assertPresent($path); - $this->assertAbsent($newpath); - - return $this->getAdapter()->copy($path, $newpath); - } - - /** - * @inheritdoc - */ - public function delete($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - return $this->getAdapter()->delete($path); - } - - /** - * @inheritdoc - */ - public function deleteDir($dirname) - { - $dirname = Util::normalizePath($dirname); - - if ($dirname === '') { - throw new RootViolationException('Root directories can not be deleted.'); - } - - return (bool) $this->getAdapter()->deleteDir($dirname); - } - - /** - * @inheritdoc - */ - public function createDir($dirname, array $config = []) - { - $dirname = Util::normalizePath($dirname); - $config = $this->prepareConfig($config); - - return (bool) $this->getAdapter()->createDir($dirname, $config); - } - - /** - * @inheritdoc - */ - public function listContents($directory = '', $recursive = false) - { - $directory = Util::normalizePath($directory); - $contents = $this->getAdapter()->listContents($directory, $recursive); - - return (new ContentListingFormatter($directory, $recursive, $this->config->get('case_sensitive', true))) - ->formatListing($contents); - } - - /** - * @inheritdoc - */ - public function getMimetype($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - if (( ! $object = $this->getAdapter()->getMimetype($path)) || ! array_key_exists('mimetype', $object)) { - return false; - } - - return $object['mimetype']; - } - - /** - * @inheritdoc - */ - public function getTimestamp($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - if (( ! $object = $this->getAdapter()->getTimestamp($path)) || ! array_key_exists('timestamp', $object)) { - return false; - } - - return (int) $object['timestamp']; - } - - /** - * @inheritdoc - */ - public function getVisibility($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - if (( ! $object = $this->getAdapter()->getVisibility($path)) || ! array_key_exists('visibility', $object)) { - return false; - } - - return $object['visibility']; - } - - /** - * @inheritdoc - */ - public function getSize($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - if (( ! $object = $this->getAdapter()->getSize($path)) || ! array_key_exists('size', $object)) { - return false; - } - - return (int) $object['size']; - } - - /** - * @inheritdoc - */ - public function setVisibility($path, $visibility) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - return (bool) $this->getAdapter()->setVisibility($path, $visibility); - } - - /** - * @inheritdoc - */ - public function getMetadata($path) - { - $path = Util::normalizePath($path); - $this->assertPresent($path); - - return $this->getAdapter()->getMetadata($path); - } - - /** - * @inheritdoc - */ - public function get($path, Handler $handler = null) - { - $path = Util::normalizePath($path); - - if ( ! $handler) { - $metadata = $this->getMetadata($path); - $handler = ($metadata && $metadata['type'] === 'file') ? new File($this, $path) : new Directory($this, $path); - } - - $handler->setPath($path); - $handler->setFilesystem($this); - - return $handler; - } - - /** - * Assert a file is present. - * - * @param string $path path to file - * - * @throws FileNotFoundException - * - * @return void - */ - public function assertPresent($path) - { - if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) { - throw new FileNotFoundException($path); - } - } - - /** - * Assert a file is absent. - * - * @param string $path path to file - * - * @throws FileExistsException - * - * @return void - */ - public function assertAbsent($path) - { - if ($this->config->get('disable_asserts', false) === false && $this->has($path)) { - throw new FileExistsException($path); - } - } -} diff --git a/vendor/league/flysystem/src/FilesystemException.php b/vendor/league/flysystem/src/FilesystemException.php deleted file mode 100644 index 3121e533d..000000000 --- a/vendor/league/flysystem/src/FilesystemException.php +++ /dev/null @@ -1,7 +0,0 @@ -path = $path; - $this->filesystem = $filesystem; - } - - /** - * Check whether the entree is a directory. - * - * @return bool - */ - public function isDir() - { - return $this->getType() === 'dir'; - } - - /** - * Check whether the entree is a file. - * - * @return bool - */ - public function isFile() - { - return $this->getType() === 'file'; - } - - /** - * Retrieve the entree type (file|dir). - * - * @return string file or dir - */ - public function getType() - { - $metadata = $this->filesystem->getMetadata($this->path); - - return $metadata ? $metadata['type'] : 'dir'; - } - - /** - * Set the Filesystem object. - * - * @param FilesystemInterface $filesystem - * - * @return $this - */ - public function setFilesystem(FilesystemInterface $filesystem) - { - $this->filesystem = $filesystem; - - return $this; - } - - /** - * Retrieve the Filesystem object. - * - * @return FilesystemInterface - */ - public function getFilesystem() - { - return $this->filesystem; - } - - /** - * Set the entree path. - * - * @param string $path - * - * @return $this - */ - public function setPath($path) - { - $this->path = $path; - - return $this; - } - - /** - * Retrieve the entree path. - * - * @return string path - */ - public function getPath() - { - return $this->path; - } - - /** - * Plugins pass-through. - * - * @param string $method - * @param array $arguments - * - * @return mixed - */ - public function __call($method, array $arguments) - { - array_unshift($arguments, $this->path); - $callback = [$this->filesystem, $method]; - - try { - return call_user_func_array($callback, $arguments); - } catch (BadMethodCallException $e) { - throw new BadMethodCallException( - 'Call to undefined method ' - . get_called_class() - . '::' . $method - ); - } - } -} diff --git a/vendor/league/flysystem/src/InvalidRootException.php b/vendor/league/flysystem/src/InvalidRootException.php deleted file mode 100644 index 468d1d58c..000000000 --- a/vendor/league/flysystem/src/InvalidRootException.php +++ /dev/null @@ -1,9 +0,0 @@ - Filesystem,] - * - * @throws InvalidArgumentException - */ - public function __construct(array $filesystems = []) - { - $this->mountFilesystems($filesystems); - } - - /** - * Mount filesystems. - * - * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,] - * - * @throws InvalidArgumentException - * - * @return $this - */ - public function mountFilesystems(array $filesystems) - { - foreach ($filesystems as $prefix => $filesystem) { - $this->mountFilesystem($prefix, $filesystem); - } - - return $this; - } - - /** - * Mount filesystems. - * - * @param string $prefix - * @param FilesystemInterface $filesystem - * - * @throws InvalidArgumentException - * - * @return $this - */ - public function mountFilesystem($prefix, FilesystemInterface $filesystem) - { - if ( ! is_string($prefix)) { - throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.'); - } - - $this->filesystems[$prefix] = $filesystem; - - return $this; - } - - /** - * Get the filesystem with the corresponding prefix. - * - * @param string $prefix - * - * @throws FilesystemNotFoundException - * - * @return FilesystemInterface - */ - public function getFilesystem($prefix) - { - if ( ! isset($this->filesystems[$prefix])) { - throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix); - } - - return $this->filesystems[$prefix]; - } - - /** - * Retrieve the prefix from an arguments array. - * - * @param array $arguments - * - * @throws InvalidArgumentException - * - * @return array [:prefix, :arguments] - */ - public function filterPrefix(array $arguments) - { - if (empty($arguments)) { - throw new InvalidArgumentException('At least one argument needed'); - } - - $path = array_shift($arguments); - - if ( ! is_string($path)) { - throw new InvalidArgumentException('First argument should be a string'); - } - - list($prefix, $path) = $this->getPrefixAndPath($path); - array_unshift($arguments, $path); - - return [$prefix, $arguments]; - } - - /** - * @param string $directory - * @param bool $recursive - * - * @throws InvalidArgumentException - * @throws FilesystemNotFoundException - * - * @return array - */ - public function listContents($directory = '', $recursive = false) - { - list($prefix, $directory) = $this->getPrefixAndPath($directory); - $filesystem = $this->getFilesystem($prefix); - $result = $filesystem->listContents($directory, $recursive); - - foreach ($result as &$file) { - $file['filesystem'] = $prefix; - } - - return $result; - } - - /** - * Call forwarder. - * - * @param string $method - * @param array $arguments - * - * @throws InvalidArgumentException - * @throws FilesystemNotFoundException - * - * @return mixed - */ - public function __call($method, $arguments) - { - list($prefix, $arguments) = $this->filterPrefix($arguments); - - return $this->invokePluginOnFilesystem($method, $arguments, $prefix); - } - - /** - * @param string $from - * @param string $to - * @param array $config - * - * @throws InvalidArgumentException - * @throws FilesystemNotFoundException - * @throws FileExistsException - * - * @return bool - */ - public function copy($from, $to, array $config = []) - { - list($prefixFrom, $from) = $this->getPrefixAndPath($from); - - $buffer = $this->getFilesystem($prefixFrom)->readStream($from); - - if ($buffer === false) { - return false; - } - - list($prefixTo, $to) = $this->getPrefixAndPath($to); - - $result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config); - - if (is_resource($buffer)) { - fclose($buffer); - } - - return $result; - } - - /** - * List with plugin adapter. - * - * @param array $keys - * @param string $directory - * @param bool $recursive - * - * @throws InvalidArgumentException - * @throws FilesystemNotFoundException - * - * @return array - */ - public function listWith(array $keys = [], $directory = '', $recursive = false) - { - list($prefix, $directory) = $this->getPrefixAndPath($directory); - $arguments = [$keys, $directory, $recursive]; - - return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix); - } - - /** - * Move a file. - * - * @param string $from - * @param string $to - * @param array $config - * - * @throws InvalidArgumentException - * @throws FilesystemNotFoundException - * - * @return bool - */ - public function move($from, $to, array $config = []) - { - list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from); - list($prefixTo, $pathTo) = $this->getPrefixAndPath($to); - - if ($prefixFrom === $prefixTo) { - $filesystem = $this->getFilesystem($prefixFrom); - $renamed = $filesystem->rename($pathFrom, $pathTo); - - if ($renamed && isset($config['visibility'])) { - return $filesystem->setVisibility($pathTo, $config['visibility']); - } - - return $renamed; - } - - $copied = $this->copy($from, $to, $config); - - if ($copied) { - return $this->delete($from); - } - - return false; - } - - /** - * Invoke a plugin on a filesystem mounted on a given prefix. - * - * @param string $method - * @param array $arguments - * @param string $prefix - * - * @throws FilesystemNotFoundException - * - * @return mixed - */ - public function invokePluginOnFilesystem($method, $arguments, $prefix) - { - $filesystem = $this->getFilesystem($prefix); - - try { - return $this->invokePlugin($method, $arguments, $filesystem); - } catch (PluginNotFoundException $e) { - // Let it pass, it's ok, don't panic. - } - - $callback = [$filesystem, $method]; - - return call_user_func_array($callback, $arguments); - } - - /** - * @param string $path - * - * @throws InvalidArgumentException - * - * @return string[] [:prefix, :path] - */ - protected function getPrefixAndPath($path) - { - if (strpos($path, '://') < 1) { - throw new InvalidArgumentException('No prefix detected in path: ' . $path); - } - - return explode('://', $path, 2); - } - - /** - * Check whether a file exists. - * - * @param string $path - * - * @return bool - */ - public function has($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->has($path); - } - - /** - * Read a file. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return string|false The file contents or false on failure. - */ - public function read($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->read($path); - } - - /** - * Retrieves a read-stream for a path. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return resource|false The path resource or false on failure. - */ - public function readStream($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->readStream($path); - } - - /** - * Get a file's metadata. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return array|false The file metadata or false on failure. - */ - public function getMetadata($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->getMetadata($path); - } - - /** - * Get a file's size. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return int|false The file size or false on failure. - */ - public function getSize($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->getSize($path); - } - - /** - * Get a file's mime-type. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return string|false The file mime-type or false on failure. - */ - public function getMimetype($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->getMimetype($path); - } - - /** - * Get a file's timestamp. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return string|false The timestamp or false on failure. - */ - public function getTimestamp($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->getTimestamp($path); - } - - /** - * Get a file's visibility. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return string|false The visibility (public|private) or false on failure. - */ - public function getVisibility($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->getVisibility($path); - } - - /** - * Write a new file. - * - * @param string $path The path of the new file. - * @param string $contents The file contents. - * @param array $config An optional configuration array. - * - * @throws FileExistsException - * - * @return bool True on success, false on failure. - */ - public function write($path, $contents, array $config = []) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->write($path, $contents, $config); - } - - /** - * Write a new file using a stream. - * - * @param string $path The path of the new file. - * @param resource $resource The file handle. - * @param array $config An optional configuration array. - * - * @throws InvalidArgumentException If $resource is not a file handle. - * @throws FileExistsException - * - * @return bool True on success, false on failure. - */ - public function writeStream($path, $resource, array $config = []) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->writeStream($path, $resource, $config); - } - - /** - * Update an existing file. - * - * @param string $path The path of the existing file. - * @param string $contents The file contents. - * @param array $config An optional configuration array. - * - * @throws FileNotFoundException - * - * @return bool True on success, false on failure. - */ - public function update($path, $contents, array $config = []) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->update($path, $contents, $config); - } - - /** - * Update an existing file using a stream. - * - * @param string $path The path of the existing file. - * @param resource $resource The file handle. - * @param array $config An optional configuration array. - * - * @throws InvalidArgumentException If $resource is not a file handle. - * @throws FileNotFoundException - * - * @return bool True on success, false on failure. - */ - public function updateStream($path, $resource, array $config = []) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->updateStream($path, $resource, $config); - } - - /** - * Rename a file. - * - * @param string $path Path to the existing file. - * @param string $newpath The new path of the file. - * - * @throws FileExistsException Thrown if $newpath exists. - * @throws FileNotFoundException Thrown if $path does not exist. - * - * @return bool True on success, false on failure. - */ - public function rename($path, $newpath) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->rename($path, $newpath); - } - - /** - * Delete a file. - * - * @param string $path - * - * @throws FileNotFoundException - * - * @return bool True on success, false on failure. - */ - public function delete($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->delete($path); - } - - /** - * Delete a directory. - * - * @param string $dirname - * - * @throws RootViolationException Thrown if $dirname is empty. - * - * @return bool True on success, false on failure. - */ - public function deleteDir($dirname) - { - list($prefix, $dirname) = $this->getPrefixAndPath($dirname); - - return $this->getFilesystem($prefix)->deleteDir($dirname); - } - - /** - * Create a directory. - * - * @param string $dirname The name of the new directory. - * @param array $config An optional configuration array. - * - * @return bool True on success, false on failure. - */ - public function createDir($dirname, array $config = []) - { - list($prefix, $dirname) = $this->getPrefixAndPath($dirname); - - return $this->getFilesystem($prefix)->createDir($dirname); - } - - /** - * Set the visibility for a file. - * - * @param string $path The path to the file. - * @param string $visibility One of 'public' or 'private'. - * - * @throws FileNotFoundException - * - * @return bool True on success, false on failure. - */ - public function setVisibility($path, $visibility) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->setVisibility($path, $visibility); - } - - /** - * Create a file or update if exists. - * - * @param string $path The path to the file. - * @param string $contents The file contents. - * @param array $config An optional configuration array. - * - * @return bool True on success, false on failure. - */ - public function put($path, $contents, array $config = []) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->put($path, $contents, $config); - } - - /** - * Create a file or update if exists. - * - * @param string $path The path to the file. - * @param resource $resource The file handle. - * @param array $config An optional configuration array. - * - * @throws InvalidArgumentException Thrown if $resource is not a resource. - * - * @return bool True on success, false on failure. - */ - public function putStream($path, $resource, array $config = []) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->putStream($path, $resource, $config); - } - - /** - * Read and delete a file. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return string|false The file contents, or false on failure. - */ - public function readAndDelete($path) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->readAndDelete($path); - } - - /** - * Get a file/directory handler. - * - * @deprecated - * - * @param string $path The path to the file. - * @param Handler $handler An optional existing handler to populate. - * - * @return Handler Either a file or directory handler. - */ - public function get($path, Handler $handler = null) - { - list($prefix, $path) = $this->getPrefixAndPath($path); - - return $this->getFilesystem($prefix)->get($path); - } -} diff --git a/vendor/league/flysystem/src/NotSupportedException.php b/vendor/league/flysystem/src/NotSupportedException.php deleted file mode 100644 index e0a989b22..000000000 --- a/vendor/league/flysystem/src/NotSupportedException.php +++ /dev/null @@ -1,37 +0,0 @@ -getPathname()); - } - - /** - * Create a new exception for a link. - * - * @param string $systemType - * - * @return static - */ - public static function forFtpSystemType($systemType) - { - $message = "The FTP system type '$systemType' is currently not supported."; - - return new static($message); - } -} diff --git a/vendor/league/flysystem/src/Plugin/AbstractPlugin.php b/vendor/league/flysystem/src/Plugin/AbstractPlugin.php deleted file mode 100644 index 0d5678976..000000000 --- a/vendor/league/flysystem/src/Plugin/AbstractPlugin.php +++ /dev/null @@ -1,24 +0,0 @@ -filesystem = $filesystem; - } -} diff --git a/vendor/league/flysystem/src/Plugin/EmptyDir.php b/vendor/league/flysystem/src/Plugin/EmptyDir.php deleted file mode 100644 index b5ae7f582..000000000 --- a/vendor/league/flysystem/src/Plugin/EmptyDir.php +++ /dev/null @@ -1,34 +0,0 @@ -filesystem->listContents($dirname, false); - - foreach ($listing as $item) { - if ($item['type'] === 'dir') { - $this->filesystem->deleteDir($item['path']); - } else { - $this->filesystem->delete($item['path']); - } - } - } -} diff --git a/vendor/league/flysystem/src/Plugin/ForcedCopy.php b/vendor/league/flysystem/src/Plugin/ForcedCopy.php deleted file mode 100644 index a41e9f3ae..000000000 --- a/vendor/league/flysystem/src/Plugin/ForcedCopy.php +++ /dev/null @@ -1,44 +0,0 @@ -filesystem->delete($newpath); - } catch (FileNotFoundException $e) { - // The destination path does not exist. That's ok. - $deleted = true; - } - - if ($deleted) { - return $this->filesystem->copy($path, $newpath); - } - - return false; - } -} diff --git a/vendor/league/flysystem/src/Plugin/ForcedRename.php b/vendor/league/flysystem/src/Plugin/ForcedRename.php deleted file mode 100644 index 3f51cd607..000000000 --- a/vendor/league/flysystem/src/Plugin/ForcedRename.php +++ /dev/null @@ -1,44 +0,0 @@ -filesystem->delete($newpath); - } catch (FileNotFoundException $e) { - // The destination path does not exist. That's ok. - $deleted = true; - } - - if ($deleted) { - return $this->filesystem->rename($path, $newpath); - } - - return false; - } -} diff --git a/vendor/league/flysystem/src/Plugin/GetWithMetadata.php b/vendor/league/flysystem/src/Plugin/GetWithMetadata.php deleted file mode 100644 index 2f13d2fd2..000000000 --- a/vendor/league/flysystem/src/Plugin/GetWithMetadata.php +++ /dev/null @@ -1,51 +0,0 @@ -filesystem->getMetadata($path); - - if ( ! $object) { - return false; - } - - $keys = array_diff($metadata, array_keys($object)); - - foreach ($keys as $key) { - if ( ! method_exists($this->filesystem, $method = 'get' . ucfirst($key))) { - throw new InvalidArgumentException('Could not fetch metadata: ' . $key); - } - - $object[$key] = $this->filesystem->{$method}($path); - } - - return $object; - } -} diff --git a/vendor/league/flysystem/src/Plugin/ListFiles.php b/vendor/league/flysystem/src/Plugin/ListFiles.php deleted file mode 100644 index 9669fe7e7..000000000 --- a/vendor/league/flysystem/src/Plugin/ListFiles.php +++ /dev/null @@ -1,35 +0,0 @@ -filesystem->listContents($directory, $recursive); - - $filter = function ($object) { - return $object['type'] === 'file'; - }; - - return array_values(array_filter($contents, $filter)); - } -} diff --git a/vendor/league/flysystem/src/Plugin/ListPaths.php b/vendor/league/flysystem/src/Plugin/ListPaths.php deleted file mode 100644 index 0889d1f8d..000000000 --- a/vendor/league/flysystem/src/Plugin/ListPaths.php +++ /dev/null @@ -1,36 +0,0 @@ -filesystem->listContents($directory, $recursive); - - foreach ($contents as $object) { - $result[] = $object['path']; - } - - return $result; - } -} diff --git a/vendor/league/flysystem/src/Plugin/ListWith.php b/vendor/league/flysystem/src/Plugin/ListWith.php deleted file mode 100644 index d64debeca..000000000 --- a/vendor/league/flysystem/src/Plugin/ListWith.php +++ /dev/null @@ -1,60 +0,0 @@ -filesystem->listContents($directory, $recursive); - - foreach ($contents as $index => $object) { - if ($object['type'] === 'file') { - $missingKeys = array_diff($keys, array_keys($object)); - $contents[$index] = array_reduce($missingKeys, [$this, 'getMetadataByName'], $object); - } - } - - return $contents; - } - - /** - * Get a meta-data value by key name. - * - * @param array $object - * @param string $key - * - * @return array - */ - protected function getMetadataByName(array $object, $key) - { - $method = 'get' . ucfirst($key); - - if ( ! method_exists($this->filesystem, $method)) { - throw new \InvalidArgumentException('Could not get meta-data for key: ' . $key); - } - - $object[$key] = $this->filesystem->{$method}($object['path']); - - return $object; - } -} diff --git a/vendor/league/flysystem/src/Plugin/PluggableTrait.php b/vendor/league/flysystem/src/Plugin/PluggableTrait.php deleted file mode 100644 index 922edfe52..000000000 --- a/vendor/league/flysystem/src/Plugin/PluggableTrait.php +++ /dev/null @@ -1,97 +0,0 @@ -plugins[$plugin->getMethod()] = $plugin; - - return $this; - } - - /** - * Find a specific plugin. - * - * @param string $method - * - * @throws PluginNotFoundException - * - * @return PluginInterface - */ - protected function findPlugin($method) - { - if ( ! isset($this->plugins[$method])) { - throw new PluginNotFoundException('Plugin not found for method: ' . $method); - } - - return $this->plugins[$method]; - } - - /** - * Invoke a plugin by method name. - * - * @param string $method - * @param array $arguments - * @param FilesystemInterface $filesystem - * - * @throws PluginNotFoundException - * - * @return mixed - */ - protected function invokePlugin($method, array $arguments, FilesystemInterface $filesystem) - { - $plugin = $this->findPlugin($method); - $plugin->setFilesystem($filesystem); - $callback = [$plugin, 'handle']; - - return call_user_func_array($callback, $arguments); - } - - /** - * Plugins pass-through. - * - * @param string $method - * @param array $arguments - * - * @throws BadMethodCallException - * - * @return mixed - */ - public function __call($method, array $arguments) - { - try { - return $this->invokePlugin($method, $arguments, $this); - } catch (PluginNotFoundException $e) { - throw new BadMethodCallException( - 'Call to undefined method ' - . get_class($this) - . '::' . $method - ); - } - } -} diff --git a/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php b/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php deleted file mode 100644 index fd1d7e7e3..000000000 --- a/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php +++ /dev/null @@ -1,10 +0,0 @@ -hash = spl_object_hash($this); - static::$safeStorage[$this->hash] = []; - } - - public function storeSafely($key, $value) - { - static::$safeStorage[$this->hash][$key] = $value; - } - - public function retrieveSafely($key) - { - if (array_key_exists($key, static::$safeStorage[$this->hash])) { - return static::$safeStorage[$this->hash][$key]; - } - } - - public function __destruct() - { - unset(static::$safeStorage[$this->hash]); - } -} diff --git a/vendor/league/flysystem/src/UnreadableFileException.php b/vendor/league/flysystem/src/UnreadableFileException.php deleted file mode 100644 index e66803383..000000000 --- a/vendor/league/flysystem/src/UnreadableFileException.php +++ /dev/null @@ -1,18 +0,0 @@ -getRealPath() - ) - ); - } -} diff --git a/vendor/league/flysystem/src/Util.php b/vendor/league/flysystem/src/Util.php deleted file mode 100644 index 1a2db718d..000000000 --- a/vendor/league/flysystem/src/Util.php +++ /dev/null @@ -1,354 +0,0 @@ - '']; - } - - /** - * Normalize a dirname return value. - * - * @param string $dirname - * - * @return string normalized dirname - */ - public static function normalizeDirname($dirname) - { - return $dirname === '.' ? '' : $dirname; - } - - /** - * Get a normalized dirname from a path. - * - * @param string $path - * - * @return string dirname - */ - public static function dirname($path) - { - return static::normalizeDirname(dirname($path)); - } - - /** - * Map result arrays. - * - * @param array $object - * @param array $map - * - * @return array mapped result - */ - public static function map(array $object, array $map) - { - $result = []; - - foreach ($map as $from => $to) { - if ( ! isset($object[$from])) { - continue; - } - - $result[$to] = $object[$from]; - } - - return $result; - } - - /** - * Normalize path. - * - * @param string $path - * - * @throws LogicException - * - * @return string - */ - public static function normalizePath($path) - { - return static::normalizeRelativePath($path); - } - - /** - * Normalize relative directories in a path. - * - * @param string $path - * - * @throws LogicException - * - * @return string - */ - public static function normalizeRelativePath($path) - { - $path = str_replace('\\', '/', $path); - $path = static::removeFunkyWhiteSpace($path); - $parts = []; - - foreach (explode('/', $path) as $part) { - switch ($part) { - case '': - case '.': - break; - - case '..': - if (empty($parts)) { - throw new LogicException( - 'Path is outside of the defined root, path: [' . $path . ']' - ); - } - array_pop($parts); - break; - - default: - $parts[] = $part; - break; - } - } - - $path = implode('/', $parts); - - return $path; - } - - /** - * Rejects unprintable characters and invalid unicode characters. - * - * @param string $path - * - * @return string $path - */ - protected static function removeFunkyWhiteSpace($path) - { - if (preg_match('#\p{C}+#u', $path)) { - throw CorruptedPathDetected::forPath($path); - } - - return $path; - } - - /** - * Normalize prefix. - * - * @param string $prefix - * @param string $separator - * - * @return string normalized path - */ - public static function normalizePrefix($prefix, $separator) - { - return rtrim($prefix, $separator) . $separator; - } - - /** - * Get content size. - * - * @param string $contents - * - * @return int content size - */ - public static function contentSize($contents) - { - return defined('MB_OVERLOAD_STRING') ? mb_strlen($contents, '8bit') : strlen($contents); - } - - /** - * Guess MIME Type based on the path of the file and it's content. - * - * @param string $path - * @param string|resource $content - * - * @return string|null MIME Type or NULL if no extension detected - */ - public static function guessMimeType($path, $content) - { - $mimeType = MimeType::detectByContent($content); - - if ( ! (empty($mimeType) || in_array($mimeType, ['application/x-empty', 'text/plain', 'text/x-asm']))) { - return $mimeType; - } - - return MimeType::detectByFilename($path); - } - - /** - * Emulate directories. - * - * @param array $listing - * - * @return array listing with emulated directories - */ - public static function emulateDirectories(array $listing) - { - $directories = []; - $listedDirectories = []; - - foreach ($listing as $object) { - [$directories, $listedDirectories] = static::emulateObjectDirectories($object, $directories, $listedDirectories); - } - - $directories = array_diff(array_unique($directories), array_unique($listedDirectories)); - - foreach ($directories as $directory) { - $listing[] = static::pathinfo($directory) + ['type' => 'dir']; - } - - return $listing; - } - - /** - * Ensure a Config instance. - * - * @param null|array|Config $config - * - * @return Config config instance - * - * @throw LogicException - */ - public static function ensureConfig($config) - { - if ($config === null) { - return new Config(); - } - - if ($config instanceof Config) { - return $config; - } - - if (is_array($config)) { - return new Config($config); - } - - throw new LogicException('A config should either be an array or a Flysystem\Config object.'); - } - - /** - * Rewind a stream. - * - * @param resource $resource - */ - public static function rewindStream($resource) - { - if (ftell($resource) !== 0 && static::isSeekableStream($resource)) { - rewind($resource); - } - } - - public static function isSeekableStream($resource) - { - $metadata = stream_get_meta_data($resource); - - return $metadata['seekable']; - } - - /** - * Get the size of a stream. - * - * @param resource $resource - * - * @return int|null stream size - */ - public static function getStreamSize($resource) - { - $stat = fstat($resource); - - if ( ! is_array($stat) || ! isset($stat['size'])) { - return null; - } - - return $stat['size']; - } - - /** - * Emulate the directories of a single object. - * - * @param array $object - * @param array $directories - * @param array $listedDirectories - * - * @return array - */ - protected static function emulateObjectDirectories(array $object, array $directories, array $listedDirectories) - { - if ($object['type'] === 'dir') { - $listedDirectories[] = $object['path']; - } - - if ( ! isset($object['dirname']) || trim($object['dirname']) === '') { - return [$directories, $listedDirectories]; - } - - $parent = $object['dirname']; - - while (isset($parent) && trim($parent) !== '' && ! in_array($parent, $directories)) { - $directories[] = $parent; - $parent = static::dirname($parent); - } - - if (isset($object['type']) && $object['type'] === 'dir') { - $listedDirectories[] = $object['path']; - - return [$directories, $listedDirectories]; - } - - return [$directories, $listedDirectories]; - } - - /** - * Returns the trailing name component of the path. - * - * @param string $path - * - * @return string - */ - private static function basename($path) - { - $separators = DIRECTORY_SEPARATOR === '/' ? '/' : '\/'; - - $path = rtrim($path, $separators); - - $basename = preg_replace('#.*?([^' . preg_quote($separators, '#') . ']+$)#', '$1', $path); - - if (DIRECTORY_SEPARATOR === '/') { - return $basename; - } - // @codeCoverageIgnoreStart - // Extra Windows path munging. This is tested via AppVeyor, but code - // coverage is not reported. - - // Handle relative paths with drive letters. c:file.txt. - while (preg_match('#^[a-zA-Z]{1}:[^\\\/]#', $basename)) { - $basename = substr($basename, 2); - } - - // Remove colon for standalone drive letter names. - if (preg_match('#^[a-zA-Z]{1}:$#', $basename)) { - $basename = rtrim($basename, ':'); - } - - return $basename; - // @codeCoverageIgnoreEnd - } -} diff --git a/vendor/league/flysystem/src/Util/ContentListingFormatter.php b/vendor/league/flysystem/src/Util/ContentListingFormatter.php deleted file mode 100644 index ae0d3b91d..000000000 --- a/vendor/league/flysystem/src/Util/ContentListingFormatter.php +++ /dev/null @@ -1,122 +0,0 @@ -directory = rtrim($directory, '/'); - $this->recursive = $recursive; - $this->caseSensitive = $caseSensitive; - } - - /** - * Format contents listing. - * - * @param array $listing - * - * @return array - */ - public function formatListing(array $listing) - { - $listing = array_filter(array_map([$this, 'addPathInfo'], $listing), [$this, 'isEntryOutOfScope']); - - return $this->sortListing(array_values($listing)); - } - - private function addPathInfo(array $entry) - { - return $entry + Util::pathinfo($entry['path']); - } - - /** - * Determine if the entry is out of scope. - * - * @param array $entry - * - * @return bool - */ - private function isEntryOutOfScope(array $entry) - { - if (empty($entry['path']) && $entry['path'] !== '0') { - return false; - } - - if ($this->recursive) { - return $this->residesInDirectory($entry); - } - - return $this->isDirectChild($entry); - } - - /** - * Check if the entry resides within the parent directory. - * - * @param array $entry - * - * @return bool - */ - private function residesInDirectory(array $entry) - { - if ($this->directory === '') { - return true; - } - - return $this->caseSensitive - ? strpos($entry['path'], $this->directory . '/') === 0 - : stripos($entry['path'], $this->directory . '/') === 0; - } - - /** - * Check if the entry is a direct child of the directory. - * - * @param array $entry - * - * @return bool - */ - private function isDirectChild(array $entry) - { - return $this->caseSensitive - ? $entry['dirname'] === $this->directory - : strcasecmp($this->directory, $entry['dirname']) === 0; - } - - /** - * @param array $listing - * - * @return array - */ - private function sortListing(array $listing) - { - usort($listing, function ($a, $b) { - return strcasecmp($a['path'], $b['path']); - }); - - return $listing; - } -} diff --git a/vendor/league/flysystem/src/Util/MimeType.php b/vendor/league/flysystem/src/Util/MimeType.php deleted file mode 100644 index 35cba3fb8..000000000 --- a/vendor/league/flysystem/src/Util/MimeType.php +++ /dev/null @@ -1,80 +0,0 @@ -detectMimeTypeFromBuffer($content); - } - - return 'text/plain'; - } - - /** - * Detects MIME Type based on file extension. - * - * @param string $extension - * - * @return string MIME Type - */ - public static function detectByFileExtension($extension) - { - return static::detector()->detectMimeTypeFromPath('artificial.' . $extension) ?: 'text/plain'; - } - - /** - * @param string $filename - * - * @return string MIME Type - */ - public static function detectByFilename($filename) - { - return static::detector()->detectMimeTypeFromPath($filename) ?: 'text/plain'; - } - - /** - * @return array Map of file extension to MIME Type - */ - public static function getExtensionToMimeTypeMap() - { - return static::$extensionToMimeTypeMap; - } -} diff --git a/vendor/league/flysystem/src/Util/StreamHasher.php b/vendor/league/flysystem/src/Util/StreamHasher.php deleted file mode 100644 index 938ec5db7..000000000 --- a/vendor/league/flysystem/src/Util/StreamHasher.php +++ /dev/null @@ -1,36 +0,0 @@ -algo = $algo; - } - - /** - * @param resource $resource - * - * @return string - */ - public function hash($resource) - { - rewind($resource); - $context = hash_init($this->algo); - hash_update_stream($context, $resource); - fclose($resource); - - return hash_final($context); - } -} diff --git a/vendor/league/mime-type-detection/CHANGELOG.md b/vendor/league/mime-type-detection/CHANGELOG.md deleted file mode 100644 index 2264f7ad8..000000000 --- a/vendor/league/mime-type-detection/CHANGELOG.md +++ /dev/null @@ -1,31 +0,0 @@ -# Changelog - -## 1.10.0 - 2022-04-11 - -### Fixed - -- Added Flysystem v1 inconclusive mime-types and made it configurable as a constructor parameter. - -## 1.9.0 - 2021-11-21 - -### Updated - -- Updated lookup - -## 1.8.0 - 2021-09-25 - -### Added - -- Added the decorator `OverridingExtensionToMimeTypeMap` which allows you to override values. - -## 1.7.0 - 2021-01-18 - -### Added - -- Added a `bufferSampleSize` parameter to the `FinfoMimeTypeDetector` class that allows you to send a reduced content sample which costs less memory. - -## 1.6.0 - 2021-01-18 - -### Changes - -- Updated generated mime-type map diff --git a/vendor/league/mime-type-detection/LICENSE b/vendor/league/mime-type-detection/LICENSE deleted file mode 100644 index 1f0165218..000000000 --- a/vendor/league/mime-type-detection/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2013-2022 Frank de Jonge - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/league/mime-type-detection/composer.json b/vendor/league/mime-type-detection/composer.json deleted file mode 100644 index 80ca1af81..000000000 --- a/vendor/league/mime-type-detection/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "league/mime-type-detection", - "description": "Mime-type detection for Flysystem", - "license": "MIT", - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "scripts": { - "test": "vendor/bin/phpunit", - "phpstan": "vendor/bin/phpstan analyse -l 6 src" - }, - "require": { - "php": "^7.2 || ^8.0", - "ext-fileinfo": "*" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.8 || ^9.3", - "phpstan/phpstan": "^0.12.68", - "friendsofphp/php-cs-fixer": "^3.2" - }, - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } - }, - "config": { - "platform": { - "php": "7.2.0" - } - } -} diff --git a/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php b/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php deleted file mode 100644 index fc0424161..000000000 --- a/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php +++ /dev/null @@ -1,13 +0,0 @@ -extensions = $extensions ?: new GeneratedExtensionToMimeTypeMap(); - } - - public function detectMimeType(string $path, $contents): ?string - { - return $this->detectMimeTypeFromPath($path); - } - - public function detectMimeTypeFromPath(string $path): ?string - { - $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); - - return $this->extensions->lookupMimeType($extension); - } - - public function detectMimeTypeFromFile(string $path): ?string - { - return $this->detectMimeTypeFromPath($path); - } - - public function detectMimeTypeFromBuffer(string $contents): ?string - { - return null; - } -} diff --git a/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php b/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php deleted file mode 100644 index 1dad7bc1a..000000000 --- a/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php +++ /dev/null @@ -1,10 +0,0 @@ - - */ - private $inconclusiveMimetypes; - - public function __construct( - string $magicFile = '', - ExtensionToMimeTypeMap $extensionMap = null, - ?int $bufferSampleSize = null, - array $inconclusiveMimetypes = self::INCONCLUSIVE_MIME_TYPES - ) { - $this->finfo = new finfo(FILEINFO_MIME_TYPE, $magicFile); - $this->extensionMap = $extensionMap ?: new GeneratedExtensionToMimeTypeMap(); - $this->bufferSampleSize = $bufferSampleSize; - $this->inconclusiveMimetypes = $inconclusiveMimetypes; - } - - public function detectMimeType(string $path, $contents): ?string - { - $mimeType = is_string($contents) - ? (@$this->finfo->buffer($this->takeSample($contents)) ?: null) - : null; - - if ($mimeType !== null && ! in_array($mimeType, $this->inconclusiveMimetypes)) { - return $mimeType; - } - - return $this->detectMimeTypeFromPath($path); - } - - public function detectMimeTypeFromPath(string $path): ?string - { - $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); - - return $this->extensionMap->lookupMimeType($extension); - } - - public function detectMimeTypeFromFile(string $path): ?string - { - return @$this->finfo->file($path) ?: null; - } - - public function detectMimeTypeFromBuffer(string $contents): ?string - { - return @$this->finfo->buffer($this->takeSample($contents)) ?: null; - } - - private function takeSample(string $contents): string - { - if ($this->bufferSampleSize === null) { - return $contents; - } - - return (string) substr($contents, 0, $this->bufferSampleSize); - } -} diff --git a/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php b/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php deleted file mode 100644 index f092388dd..000000000 --- a/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php +++ /dev/null @@ -1,1227 +0,0 @@ - 'application/vnd.1000minds.decision-model+xml', - '3dml' => 'text/vnd.in3d.3dml', - '3ds' => 'image/x-3ds', - '3g2' => 'video/3gpp2', - '3gp' => 'video/3gp', - '3gpp' => 'video/3gpp', - '3mf' => 'model/3mf', - '7z' => 'application/x-7z-compressed', - '7zip' => 'application/x-7z-compressed', - '123' => 'application/vnd.lotus-1-2-3', - 'aab' => 'application/x-authorware-bin', - 'aac' => 'audio/x-acc', - 'aam' => 'application/x-authorware-map', - 'aas' => 'application/x-authorware-seg', - 'abw' => 'application/x-abiword', - 'ac' => 'application/vnd.nokia.n-gage.ac+xml', - 'ac3' => 'audio/ac3', - 'acc' => 'application/vnd.americandynamics.acc', - 'ace' => 'application/x-ace-compressed', - 'acu' => 'application/vnd.acucobol', - 'acutc' => 'application/vnd.acucorp', - 'adp' => 'audio/adpcm', - 'aep' => 'application/vnd.audiograph', - 'afm' => 'application/x-font-type1', - 'afp' => 'application/vnd.ibm.modcap', - 'age' => 'application/vnd.age', - 'ahead' => 'application/vnd.ahead.space', - 'ai' => 'application/pdf', - 'aif' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'air' => 'application/vnd.adobe.air-application-installer-package+zip', - 'ait' => 'application/vnd.dvb.ait', - 'ami' => 'application/vnd.amiga.ami', - 'amr' => 'audio/amr', - 'apk' => 'application/vnd.android.package-archive', - 'apng' => 'image/apng', - 'appcache' => 'text/cache-manifest', - 'application' => 'application/x-ms-application', - 'apr' => 'application/vnd.lotus-approach', - 'arc' => 'application/x-freearc', - 'arj' => 'application/x-arj', - 'asc' => 'application/pgp-signature', - 'asf' => 'video/x-ms-asf', - 'asm' => 'text/x-asm', - 'aso' => 'application/vnd.accpac.simply.aso', - 'asx' => 'video/x-ms-asf', - 'atc' => 'application/vnd.acucorp', - 'atom' => 'application/atom+xml', - 'atomcat' => 'application/atomcat+xml', - 'atomdeleted' => 'application/atomdeleted+xml', - 'atomsvc' => 'application/atomsvc+xml', - 'atx' => 'application/vnd.antix.game-component', - 'au' => 'audio/x-au', - 'avci' => 'image/avci', - 'avcs' => 'image/avcs', - 'avi' => 'video/x-msvideo', - 'avif' => 'image/avif', - 'aw' => 'application/applixware', - 'azf' => 'application/vnd.airzip.filesecure.azf', - 'azs' => 'application/vnd.airzip.filesecure.azs', - 'azv' => 'image/vnd.airzip.accelerator.azv', - 'azw' => 'application/vnd.amazon.ebook', - 'b16' => 'image/vnd.pco.b16', - 'bat' => 'application/x-msdownload', - 'bcpio' => 'application/x-bcpio', - 'bdf' => 'application/x-font-bdf', - 'bdm' => 'application/vnd.syncml.dm+wbxml', - 'bdoc' => 'application/x-bdoc', - 'bed' => 'application/vnd.realvnc.bed', - 'bh2' => 'application/vnd.fujitsu.oasysprs', - 'bin' => 'application/octet-stream', - 'blb' => 'application/x-blorb', - 'blorb' => 'application/x-blorb', - 'bmi' => 'application/vnd.bmi', - 'bmml' => 'application/vnd.balsamiq.bmml+xml', - 'bmp' => 'image/bmp', - 'book' => 'application/vnd.framemaker', - 'box' => 'application/vnd.previewsystems.box', - 'boz' => 'application/x-bzip2', - 'bpk' => 'application/octet-stream', - 'bpmn' => 'application/octet-stream', - 'bsp' => 'model/vnd.valve.source.compiled-map', - 'btif' => 'image/prs.btif', - 'buffer' => 'application/octet-stream', - 'bz' => 'application/x-bzip', - 'bz2' => 'application/x-bzip2', - 'c' => 'text/x-c', - 'c4d' => 'application/vnd.clonk.c4group', - 'c4f' => 'application/vnd.clonk.c4group', - 'c4g' => 'application/vnd.clonk.c4group', - 'c4p' => 'application/vnd.clonk.c4group', - 'c4u' => 'application/vnd.clonk.c4group', - 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', - 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', - 'cab' => 'application/vnd.ms-cab-compressed', - 'caf' => 'audio/x-caf', - 'cap' => 'application/vnd.tcpdump.pcap', - 'car' => 'application/vnd.curl.car', - 'cat' => 'application/vnd.ms-pki.seccat', - 'cb7' => 'application/x-cbr', - 'cba' => 'application/x-cbr', - 'cbr' => 'application/x-cbr', - 'cbt' => 'application/x-cbr', - 'cbz' => 'application/x-cbr', - 'cc' => 'text/x-c', - 'cco' => 'application/x-cocoa', - 'cct' => 'application/x-director', - 'ccxml' => 'application/ccxml+xml', - 'cdbcmsg' => 'application/vnd.contact.cmsg', - 'cdf' => 'application/x-netcdf', - 'cdfx' => 'application/cdfx+xml', - 'cdkey' => 'application/vnd.mediastation.cdkey', - 'cdmia' => 'application/cdmi-capability', - 'cdmic' => 'application/cdmi-container', - 'cdmid' => 'application/cdmi-domain', - 'cdmio' => 'application/cdmi-object', - 'cdmiq' => 'application/cdmi-queue', - 'cdr' => 'application/cdr', - 'cdx' => 'chemical/x-cdx', - 'cdxml' => 'application/vnd.chemdraw+xml', - 'cdy' => 'application/vnd.cinderella', - 'cer' => 'application/pkix-cert', - 'cfs' => 'application/x-cfs-compressed', - 'cgm' => 'image/cgm', - 'chat' => 'application/x-chat', - 'chm' => 'application/vnd.ms-htmlhelp', - 'chrt' => 'application/vnd.kde.kchart', - 'cif' => 'chemical/x-cif', - 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', - 'cil' => 'application/vnd.ms-artgalry', - 'cjs' => 'application/node', - 'cla' => 'application/vnd.claymore', - 'class' => 'application/octet-stream', - 'clkk' => 'application/vnd.crick.clicker.keyboard', - 'clkp' => 'application/vnd.crick.clicker.palette', - 'clkt' => 'application/vnd.crick.clicker.template', - 'clkw' => 'application/vnd.crick.clicker.wordbank', - 'clkx' => 'application/vnd.crick.clicker', - 'clp' => 'application/x-msclip', - 'cmc' => 'application/vnd.cosmocaller', - 'cmdf' => 'chemical/x-cmdf', - 'cml' => 'chemical/x-cml', - 'cmp' => 'application/vnd.yellowriver-custom-menu', - 'cmx' => 'image/x-cmx', - 'cod' => 'application/vnd.rim.cod', - 'coffee' => 'text/coffeescript', - 'com' => 'application/x-msdownload', - 'conf' => 'text/plain', - 'cpio' => 'application/x-cpio', - 'cpl' => 'application/cpl+xml', - 'cpp' => 'text/x-c', - 'cpt' => 'application/mac-compactpro', - 'crd' => 'application/x-mscardfile', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'crx' => 'application/x-chrome-extension', - 'cryptonote' => 'application/vnd.rig.cryptonote', - 'csh' => 'application/x-csh', - 'csl' => 'application/vnd.citationstyles.style+xml', - 'csml' => 'chemical/x-csml', - 'csp' => 'application/vnd.commonspace', - 'csr' => 'application/octet-stream', - 'css' => 'text/css', - 'cst' => 'application/x-director', - 'csv' => 'text/csv', - 'cu' => 'application/cu-seeme', - 'curl' => 'text/vnd.curl', - 'cww' => 'application/prs.cww', - 'cxt' => 'application/x-director', - 'cxx' => 'text/x-c', - 'dae' => 'model/vnd.collada+xml', - 'daf' => 'application/vnd.mobius.daf', - 'dart' => 'application/vnd.dart', - 'dataless' => 'application/vnd.fdsn.seed', - 'davmount' => 'application/davmount+xml', - 'dbf' => 'application/vnd.dbf', - 'dbk' => 'application/docbook+xml', - 'dcr' => 'application/x-director', - 'dcurl' => 'text/vnd.curl.dcurl', - 'dd2' => 'application/vnd.oma.dd2+xml', - 'ddd' => 'application/vnd.fujixerox.ddd', - 'ddf' => 'application/vnd.syncml.dmddf+xml', - 'dds' => 'image/vnd.ms-dds', - 'deb' => 'application/x-debian-package', - 'def' => 'text/plain', - 'deploy' => 'application/octet-stream', - 'der' => 'application/x-x509-ca-cert', - 'dfac' => 'application/vnd.dreamfactory', - 'dgc' => 'application/x-dgc-compressed', - 'dic' => 'text/x-c', - 'dir' => 'application/x-director', - 'dis' => 'application/vnd.mobius.dis', - 'disposition-notification' => 'message/disposition-notification', - 'dist' => 'application/octet-stream', - 'distz' => 'application/octet-stream', - 'djv' => 'image/vnd.djvu', - 'djvu' => 'image/vnd.djvu', - 'dll' => 'application/octet-stream', - 'dmg' => 'application/x-apple-diskimage', - 'dmn' => 'application/octet-stream', - 'dmp' => 'application/vnd.tcpdump.pcap', - 'dms' => 'application/octet-stream', - 'dna' => 'application/vnd.dna', - 'doc' => 'application/msword', - 'docm' => 'application/vnd.ms-word.template.macroEnabled.12', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dot' => 'application/msword', - 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'dp' => 'application/vnd.osgi.dp', - 'dpg' => 'application/vnd.dpgraph', - 'dra' => 'audio/vnd.dra', - 'drle' => 'image/dicom-rle', - 'dsc' => 'text/prs.lines.tag', - 'dssc' => 'application/dssc+der', - 'dtb' => 'application/x-dtbook+xml', - 'dtd' => 'application/xml-dtd', - 'dts' => 'audio/vnd.dts', - 'dtshd' => 'audio/vnd.dts.hd', - 'dump' => 'application/octet-stream', - 'dvb' => 'video/vnd.dvb.file', - 'dvi' => 'application/x-dvi', - 'dwd' => 'application/atsc-dwd+xml', - 'dwf' => 'model/vnd.dwf', - 'dwg' => 'image/vnd.dwg', - 'dxf' => 'image/vnd.dxf', - 'dxp' => 'application/vnd.spotfire.dxp', - 'dxr' => 'application/x-director', - 'ear' => 'application/java-archive', - 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', - 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', - 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', - 'ecma' => 'application/ecmascript', - 'edm' => 'application/vnd.novadigm.edm', - 'edx' => 'application/vnd.novadigm.edx', - 'efif' => 'application/vnd.picsel', - 'ei6' => 'application/vnd.pg.osasli', - 'elc' => 'application/octet-stream', - 'emf' => 'image/emf', - 'eml' => 'message/rfc822', - 'emma' => 'application/emma+xml', - 'emotionml' => 'application/emotionml+xml', - 'emz' => 'application/x-msmetafile', - 'eol' => 'audio/vnd.digital-winds', - 'eot' => 'application/vnd.ms-fontobject', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'es' => 'application/ecmascript', - 'es3' => 'application/vnd.eszigno3+xml', - 'esa' => 'application/vnd.osgi.subsystem', - 'esf' => 'application/vnd.epson.esf', - 'et3' => 'application/vnd.eszigno3+xml', - 'etx' => 'text/x-setext', - 'eva' => 'application/x-eva', - 'evy' => 'application/x-envoy', - 'exe' => 'application/octet-stream', - 'exi' => 'application/exi', - 'exp' => 'application/express', - 'exr' => 'image/aces', - 'ext' => 'application/vnd.novadigm.ext', - 'ez' => 'application/andrew-inset', - 'ez2' => 'application/vnd.ezpix-album', - 'ez3' => 'application/vnd.ezpix-package', - 'f' => 'text/x-fortran', - 'f4v' => 'video/mp4', - 'f77' => 'text/x-fortran', - 'f90' => 'text/x-fortran', - 'fbs' => 'image/vnd.fastbidsheet', - 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', - 'fcs' => 'application/vnd.isac.fcs', - 'fdf' => 'application/vnd.fdf', - 'fdt' => 'application/fdt+xml', - 'fe_launch' => 'application/vnd.denovo.fcselayout-link', - 'fg5' => 'application/vnd.fujitsu.oasysgp', - 'fgd' => 'application/x-director', - 'fh' => 'image/x-freehand', - 'fh4' => 'image/x-freehand', - 'fh5' => 'image/x-freehand', - 'fh7' => 'image/x-freehand', - 'fhc' => 'image/x-freehand', - 'fig' => 'application/x-xfig', - 'fits' => 'image/fits', - 'flac' => 'audio/x-flac', - 'fli' => 'video/x-fli', - 'flo' => 'application/vnd.micrografx.flo', - 'flv' => 'video/x-flv', - 'flw' => 'application/vnd.kde.kivio', - 'flx' => 'text/vnd.fmi.flexstor', - 'fly' => 'text/vnd.fly', - 'fm' => 'application/vnd.framemaker', - 'fnc' => 'application/vnd.frogans.fnc', - 'fo' => 'application/vnd.software602.filler.form+xml', - 'for' => 'text/x-fortran', - 'fpx' => 'image/vnd.fpx', - 'frame' => 'application/vnd.framemaker', - 'fsc' => 'application/vnd.fsc.weblaunch', - 'fst' => 'image/vnd.fst', - 'ftc' => 'application/vnd.fluxtime.clip', - 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', - 'fvt' => 'video/vnd.fvt', - 'fxp' => 'application/vnd.adobe.fxp', - 'fxpl' => 'application/vnd.adobe.fxp', - 'fzs' => 'application/vnd.fuzzysheet', - 'g2w' => 'application/vnd.geoplan', - 'g3' => 'image/g3fax', - 'g3w' => 'application/vnd.geospace', - 'gac' => 'application/vnd.groove-account', - 'gam' => 'application/x-tads', - 'gbr' => 'application/rpki-ghostbusters', - 'gca' => 'application/x-gca-compressed', - 'gdl' => 'model/vnd.gdl', - 'gdoc' => 'application/vnd.google-apps.document', - 'ged' => 'text/vnd.familysearch.gedcom', - 'geo' => 'application/vnd.dynageo', - 'geojson' => 'application/geo+json', - 'gex' => 'application/vnd.geometry-explorer', - 'ggb' => 'application/vnd.geogebra.file', - 'ggt' => 'application/vnd.geogebra.tool', - 'ghf' => 'application/vnd.groove-help', - 'gif' => 'image/gif', - 'gim' => 'application/vnd.groove-identity-message', - 'glb' => 'model/gltf-binary', - 'gltf' => 'model/gltf+json', - 'gml' => 'application/gml+xml', - 'gmx' => 'application/vnd.gmx', - 'gnumeric' => 'application/x-gnumeric', - 'gpg' => 'application/gpg-keys', - 'gph' => 'application/vnd.flographit', - 'gpx' => 'application/gpx+xml', - 'gqf' => 'application/vnd.grafeq', - 'gqs' => 'application/vnd.grafeq', - 'gram' => 'application/srgs', - 'gramps' => 'application/x-gramps-xml', - 'gre' => 'application/vnd.geometry-explorer', - 'grv' => 'application/vnd.groove-injector', - 'grxml' => 'application/srgs+xml', - 'gsf' => 'application/x-font-ghostscript', - 'gsheet' => 'application/vnd.google-apps.spreadsheet', - 'gslides' => 'application/vnd.google-apps.presentation', - 'gtar' => 'application/x-gtar', - 'gtm' => 'application/vnd.groove-tool-message', - 'gtw' => 'model/vnd.gtw', - 'gv' => 'text/vnd.graphviz', - 'gxf' => 'application/gxf', - 'gxt' => 'application/vnd.geonext', - 'gz' => 'application/gzip', - 'gzip' => 'application/gzip', - 'h' => 'text/x-c', - 'h261' => 'video/h261', - 'h263' => 'video/h263', - 'h264' => 'video/h264', - 'hal' => 'application/vnd.hal+xml', - 'hbci' => 'application/vnd.hbci', - 'hbs' => 'text/x-handlebars-template', - 'hdd' => 'application/x-virtualbox-hdd', - 'hdf' => 'application/x-hdf', - 'heic' => 'image/heic', - 'heics' => 'image/heic-sequence', - 'heif' => 'image/heif', - 'heifs' => 'image/heif-sequence', - 'hej2' => 'image/hej2k', - 'held' => 'application/atsc-held+xml', - 'hh' => 'text/x-c', - 'hjson' => 'application/hjson', - 'hlp' => 'application/winhlp', - 'hpgl' => 'application/vnd.hp-hpgl', - 'hpid' => 'application/vnd.hp-hpid', - 'hps' => 'application/vnd.hp-hps', - 'hqx' => 'application/mac-binhex40', - 'hsj2' => 'image/hsj2', - 'htc' => 'text/x-component', - 'htke' => 'application/vnd.kenameaapp', - 'htm' => 'text/html', - 'html' => 'text/html', - 'hvd' => 'application/vnd.yamaha.hv-dic', - 'hvp' => 'application/vnd.yamaha.hv-voice', - 'hvs' => 'application/vnd.yamaha.hv-script', - 'i2g' => 'application/vnd.intergeo', - 'icc' => 'application/vnd.iccprofile', - 'ice' => 'x-conference/x-cooltalk', - 'icm' => 'application/vnd.iccprofile', - 'ico' => 'image/x-icon', - 'ics' => 'text/calendar', - 'ief' => 'image/ief', - 'ifb' => 'text/calendar', - 'ifm' => 'application/vnd.shana.informed.formdata', - 'iges' => 'model/iges', - 'igl' => 'application/vnd.igloader', - 'igm' => 'application/vnd.insors.igm', - 'igs' => 'model/iges', - 'igx' => 'application/vnd.micrografx.igx', - 'iif' => 'application/vnd.shana.informed.interchange', - 'img' => 'application/octet-stream', - 'imp' => 'application/vnd.accpac.simply.imp', - 'ims' => 'application/vnd.ms-ims', - 'in' => 'text/plain', - 'ini' => 'text/plain', - 'ink' => 'application/inkml+xml', - 'inkml' => 'application/inkml+xml', - 'install' => 'application/x-install-instructions', - 'iota' => 'application/vnd.astraea-software.iota', - 'ipfix' => 'application/ipfix', - 'ipk' => 'application/vnd.shana.informed.package', - 'irm' => 'application/vnd.ibm.rights-management', - 'irp' => 'application/vnd.irepository.package+xml', - 'iso' => 'application/x-iso9660-image', - 'itp' => 'application/vnd.shana.informed.formtemplate', - 'its' => 'application/its+xml', - 'ivp' => 'application/vnd.immervision-ivp', - 'ivu' => 'application/vnd.immervision-ivu', - 'jad' => 'text/vnd.sun.j2me.app-descriptor', - 'jade' => 'text/jade', - 'jam' => 'application/vnd.jam', - 'jar' => 'application/java-archive', - 'jardiff' => 'application/x-java-archive-diff', - 'java' => 'text/x-java-source', - 'jhc' => 'image/jphc', - 'jisp' => 'application/vnd.jisp', - 'jls' => 'image/jls', - 'jlt' => 'application/vnd.hp-jlyt', - 'jng' => 'image/x-jng', - 'jnlp' => 'application/x-java-jnlp-file', - 'joda' => 'application/vnd.joost.joda-archive', - 'jp2' => 'image/jp2', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpf' => 'image/jpx', - 'jpg' => 'image/jpeg', - 'jpg2' => 'image/jp2', - 'jpgm' => 'video/jpm', - 'jpgv' => 'video/jpeg', - 'jph' => 'image/jph', - 'jpm' => 'video/jpm', - 'jpx' => 'image/jpx', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'json5' => 'application/json5', - 'jsonld' => 'application/ld+json', - 'jsonml' => 'application/jsonml+json', - 'jsx' => 'text/jsx', - 'jxr' => 'image/jxr', - 'jxra' => 'image/jxra', - 'jxrs' => 'image/jxrs', - 'jxs' => 'image/jxs', - 'jxsc' => 'image/jxsc', - 'jxsi' => 'image/jxsi', - 'jxss' => 'image/jxss', - 'kar' => 'audio/midi', - 'karbon' => 'application/vnd.kde.karbon', - 'kdb' => 'application/octet-stream', - 'kdbx' => 'application/x-keepass2', - 'key' => 'application/x-iwork-keynote-sffkey', - 'kfo' => 'application/vnd.kde.kformula', - 'kia' => 'application/vnd.kidspiration', - 'kml' => 'application/vnd.google-earth.kml+xml', - 'kmz' => 'application/vnd.google-earth.kmz', - 'kne' => 'application/vnd.kinar', - 'knp' => 'application/vnd.kinar', - 'kon' => 'application/vnd.kde.kontour', - 'kpr' => 'application/vnd.kde.kpresenter', - 'kpt' => 'application/vnd.kde.kpresenter', - 'kpxx' => 'application/vnd.ds-keypoint', - 'ksp' => 'application/vnd.kde.kspread', - 'ktr' => 'application/vnd.kahootz', - 'ktx' => 'image/ktx', - 'ktx2' => 'image/ktx2', - 'ktz' => 'application/vnd.kahootz', - 'kwd' => 'application/vnd.kde.kword', - 'kwt' => 'application/vnd.kde.kword', - 'lasxml' => 'application/vnd.las.las+xml', - 'latex' => 'application/x-latex', - 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', - 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', - 'les' => 'application/vnd.hhe.lesson-player', - 'less' => 'text/less', - 'lgr' => 'application/lgr+xml', - 'lha' => 'application/octet-stream', - 'link66' => 'application/vnd.route66.link66+xml', - 'list' => 'text/plain', - 'list3820' => 'application/vnd.ibm.modcap', - 'listafp' => 'application/vnd.ibm.modcap', - 'litcoffee' => 'text/coffeescript', - 'lnk' => 'application/x-ms-shortcut', - 'log' => 'text/plain', - 'lostxml' => 'application/lost+xml', - 'lrf' => 'application/octet-stream', - 'lrm' => 'application/vnd.ms-lrm', - 'ltf' => 'application/vnd.frogans.ltf', - 'lua' => 'text/x-lua', - 'luac' => 'application/x-lua-bytecode', - 'lvp' => 'audio/vnd.lucent.voice', - 'lwp' => 'application/vnd.lotus-wordpro', - 'lzh' => 'application/octet-stream', - 'm1v' => 'video/mpeg', - 'm2a' => 'audio/mpeg', - 'm2v' => 'video/mpeg', - 'm3a' => 'audio/mpeg', - 'm3u' => 'text/plain', - 'm3u8' => 'application/vnd.apple.mpegurl', - 'm4a' => 'audio/x-m4a', - 'm4p' => 'application/mp4', - 'm4s' => 'video/iso.segment', - 'm4u' => 'application/vnd.mpegurl', - 'm4v' => 'video/x-m4v', - 'm13' => 'application/x-msmediaview', - 'm14' => 'application/x-msmediaview', - 'm21' => 'application/mp21', - 'ma' => 'application/mathematica', - 'mads' => 'application/mads+xml', - 'maei' => 'application/mmt-aei+xml', - 'mag' => 'application/vnd.ecowin.chart', - 'maker' => 'application/vnd.framemaker', - 'man' => 'text/troff', - 'manifest' => 'text/cache-manifest', - 'map' => 'application/json', - 'mar' => 'application/octet-stream', - 'markdown' => 'text/markdown', - 'mathml' => 'application/mathml+xml', - 'mb' => 'application/mathematica', - 'mbk' => 'application/vnd.mobius.mbk', - 'mbox' => 'application/mbox', - 'mc1' => 'application/vnd.medcalcdata', - 'mcd' => 'application/vnd.mcd', - 'mcurl' => 'text/vnd.curl.mcurl', - 'md' => 'text/markdown', - 'mdb' => 'application/x-msaccess', - 'mdi' => 'image/vnd.ms-modi', - 'mdx' => 'text/mdx', - 'me' => 'text/troff', - 'mesh' => 'model/mesh', - 'meta4' => 'application/metalink4+xml', - 'metalink' => 'application/metalink+xml', - 'mets' => 'application/mets+xml', - 'mfm' => 'application/vnd.mfmp', - 'mft' => 'application/rpki-manifest', - 'mgp' => 'application/vnd.osgeo.mapguide.package', - 'mgz' => 'application/vnd.proteus.magazine', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mie' => 'application/x-mie', - 'mif' => 'application/vnd.mif', - 'mime' => 'message/rfc822', - 'mj2' => 'video/mj2', - 'mjp2' => 'video/mj2', - 'mjs' => 'application/javascript', - 'mk3d' => 'video/x-matroska', - 'mka' => 'audio/x-matroska', - 'mkd' => 'text/x-markdown', - 'mks' => 'video/x-matroska', - 'mkv' => 'video/x-matroska', - 'mlp' => 'application/vnd.dolby.mlp', - 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', - 'mmf' => 'application/vnd.smaf', - 'mml' => 'text/mathml', - 'mmr' => 'image/vnd.fujixerox.edmics-mmr', - 'mng' => 'video/x-mng', - 'mny' => 'application/x-msmoney', - 'mobi' => 'application/x-mobipocket-ebook', - 'mods' => 'application/mods+xml', - 'mov' => 'video/quicktime', - 'movie' => 'video/x-sgi-movie', - 'mp2' => 'audio/mpeg', - 'mp2a' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mp4a' => 'audio/mp4', - 'mp4s' => 'application/mp4', - 'mp4v' => 'video/mp4', - 'mp21' => 'application/mp21', - 'mpc' => 'application/vnd.mophun.certificate', - 'mpd' => 'application/dash+xml', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpf' => 'application/media-policy-dataset+xml', - 'mpg' => 'video/mpeg', - 'mpg4' => 'video/mp4', - 'mpga' => 'audio/mpeg', - 'mpkg' => 'application/vnd.apple.installer+xml', - 'mpm' => 'application/vnd.blueice.multipass', - 'mpn' => 'application/vnd.mophun.application', - 'mpp' => 'application/vnd.ms-project', - 'mpt' => 'application/vnd.ms-project', - 'mpy' => 'application/vnd.ibm.minipay', - 'mqy' => 'application/vnd.mobius.mqy', - 'mrc' => 'application/marc', - 'mrcx' => 'application/marcxml+xml', - 'ms' => 'text/troff', - 'mscml' => 'application/mediaservercontrol+xml', - 'mseed' => 'application/vnd.fdsn.mseed', - 'mseq' => 'application/vnd.mseq', - 'msf' => 'application/vnd.epson.msf', - 'msg' => 'application/vnd.ms-outlook', - 'msh' => 'model/mesh', - 'msi' => 'application/x-msdownload', - 'msl' => 'application/vnd.mobius.msl', - 'msm' => 'application/octet-stream', - 'msp' => 'application/octet-stream', - 'msty' => 'application/vnd.muvee.style', - 'mtl' => 'model/mtl', - 'mts' => 'model/vnd.mts', - 'mus' => 'application/vnd.musician', - 'musd' => 'application/mmt-usd+xml', - 'musicxml' => 'application/vnd.recordare.musicxml+xml', - 'mvb' => 'application/x-msmediaview', - 'mvt' => 'application/vnd.mapbox-vector-tile', - 'mwf' => 'application/vnd.mfer', - 'mxf' => 'application/mxf', - 'mxl' => 'application/vnd.recordare.musicxml', - 'mxmf' => 'audio/mobile-xmf', - 'mxml' => 'application/xv+xml', - 'mxs' => 'application/vnd.triscape.mxs', - 'mxu' => 'video/vnd.mpegurl', - 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', - 'n3' => 'text/n3', - 'nb' => 'application/mathematica', - 'nbp' => 'application/vnd.wolfram.player', - 'nc' => 'application/x-netcdf', - 'ncx' => 'application/x-dtbncx+xml', - 'nfo' => 'text/x-nfo', - 'ngdat' => 'application/vnd.nokia.n-gage.data', - 'nitf' => 'application/vnd.nitf', - 'nlu' => 'application/vnd.neurolanguage.nlu', - 'nml' => 'application/vnd.enliven', - 'nnd' => 'application/vnd.noblenet-directory', - 'nns' => 'application/vnd.noblenet-sealer', - 'nnw' => 'application/vnd.noblenet-web', - 'npx' => 'image/vnd.net-fpx', - 'nq' => 'application/n-quads', - 'nsc' => 'application/x-conference', - 'nsf' => 'application/vnd.lotus-notes', - 'nt' => 'application/n-triples', - 'ntf' => 'application/vnd.nitf', - 'numbers' => 'application/x-iwork-numbers-sffnumbers', - 'nzb' => 'application/x-nzb', - 'oa2' => 'application/vnd.fujitsu.oasys2', - 'oa3' => 'application/vnd.fujitsu.oasys3', - 'oas' => 'application/vnd.fujitsu.oasys', - 'obd' => 'application/x-msbinder', - 'obgx' => 'application/vnd.openblox.game+xml', - 'obj' => 'model/obj', - 'oda' => 'application/oda', - 'odb' => 'application/vnd.oasis.opendocument.database', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odf' => 'application/vnd.oasis.opendocument.formula', - 'odft' => 'application/vnd.oasis.opendocument.formula-template', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odi' => 'application/vnd.oasis.opendocument.image', - 'odm' => 'application/vnd.oasis.opendocument.text-master', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odt' => 'application/vnd.oasis.opendocument.text', - 'oga' => 'audio/ogg', - 'ogex' => 'model/vnd.opengex', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'omdoc' => 'application/omdoc+xml', - 'onepkg' => 'application/onenote', - 'onetmp' => 'application/onenote', - 'onetoc' => 'application/onenote', - 'onetoc2' => 'application/onenote', - 'opf' => 'application/oebps-package+xml', - 'opml' => 'text/x-opml', - 'oprc' => 'application/vnd.palm', - 'opus' => 'audio/ogg', - 'org' => 'text/x-org', - 'osf' => 'application/vnd.yamaha.openscoreformat', - 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', - 'osm' => 'application/vnd.openstreetmap.data+xml', - 'otc' => 'application/vnd.oasis.opendocument.chart-template', - 'otf' => 'font/otf', - 'otg' => 'application/vnd.oasis.opendocument.graphics-template', - 'oth' => 'application/vnd.oasis.opendocument.text-web', - 'oti' => 'application/vnd.oasis.opendocument.image-template', - 'otp' => 'application/vnd.oasis.opendocument.presentation-template', - 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', - 'ott' => 'application/vnd.oasis.opendocument.text-template', - 'ova' => 'application/x-virtualbox-ova', - 'ovf' => 'application/x-virtualbox-ovf', - 'owl' => 'application/rdf+xml', - 'oxps' => 'application/oxps', - 'oxt' => 'application/vnd.openofficeorg.extension', - 'p' => 'text/x-pascal', - 'p7a' => 'application/x-pkcs7-signature', - 'p7b' => 'application/x-pkcs7-certificates', - 'p7c' => 'application/pkcs7-mime', - 'p7m' => 'application/pkcs7-mime', - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'p8' => 'application/pkcs8', - 'p10' => 'application/x-pkcs10', - 'p12' => 'application/x-pkcs12', - 'pac' => 'application/x-ns-proxy-autoconfig', - 'pages' => 'application/x-iwork-pages-sffpages', - 'pas' => 'text/x-pascal', - 'paw' => 'application/vnd.pawaafile', - 'pbd' => 'application/vnd.powerbuilder6', - 'pbm' => 'image/x-portable-bitmap', - 'pcap' => 'application/vnd.tcpdump.pcap', - 'pcf' => 'application/x-font-pcf', - 'pcl' => 'application/vnd.hp-pcl', - 'pclxl' => 'application/vnd.hp-pclxl', - 'pct' => 'image/x-pict', - 'pcurl' => 'application/vnd.curl.pcurl', - 'pcx' => 'image/x-pcx', - 'pdb' => 'application/x-pilot', - 'pde' => 'text/x-processing', - 'pdf' => 'application/pdf', - 'pem' => 'application/x-x509-user-cert', - 'pfa' => 'application/x-font-type1', - 'pfb' => 'application/x-font-type1', - 'pfm' => 'application/x-font-type1', - 'pfr' => 'application/font-tdpfr', - 'pfx' => 'application/x-pkcs12', - 'pgm' => 'image/x-portable-graymap', - 'pgn' => 'application/x-chess-pgn', - 'pgp' => 'application/pgp', - 'phar' => 'application/octet-stream', - 'php' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'phtml' => 'application/x-httpd-php', - 'pic' => 'image/x-pict', - 'pkg' => 'application/octet-stream', - 'pki' => 'application/pkixcmp', - 'pkipath' => 'application/pkix-pkipath', - 'pkpass' => 'application/vnd.apple.pkpass', - 'pl' => 'application/x-perl', - 'plb' => 'application/vnd.3gpp.pic-bw-large', - 'plc' => 'application/vnd.mobius.plc', - 'plf' => 'application/vnd.pocketlearn', - 'pls' => 'application/pls+xml', - 'pm' => 'application/x-perl', - 'pml' => 'application/vnd.ctc-posml', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'portpkg' => 'application/vnd.macports.portpkg', - 'pot' => 'application/vnd.ms-powerpoint', - 'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', - 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'ppa' => 'application/vnd.ms-powerpoint', - 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', - 'ppd' => 'application/vnd.cups-ppd', - 'ppm' => 'image/x-portable-pixmap', - 'pps' => 'application/vnd.ms-powerpoint', - 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', - 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - 'ppt' => 'application/powerpoint', - 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'pqa' => 'application/vnd.palm', - 'prc' => 'model/prc', - 'pre' => 'application/vnd.lotus-freelance', - 'prf' => 'application/pics-rules', - 'provx' => 'application/provenance+xml', - 'ps' => 'application/postscript', - 'psb' => 'application/vnd.3gpp.pic-bw-small', - 'psd' => 'application/x-photoshop', - 'psf' => 'application/x-font-linux-psf', - 'pskcxml' => 'application/pskc+xml', - 'pti' => 'image/prs.pti', - 'ptid' => 'application/vnd.pvi.ptid1', - 'pub' => 'application/x-mspublisher', - 'pvb' => 'application/vnd.3gpp.pic-bw-var', - 'pwn' => 'application/vnd.3m.post-it-notes', - 'pya' => 'audio/vnd.ms-playready.media.pya', - 'pyv' => 'video/vnd.ms-playready.media.pyv', - 'qam' => 'application/vnd.epson.quickanime', - 'qbo' => 'application/vnd.intu.qbo', - 'qfx' => 'application/vnd.intu.qfx', - 'qps' => 'application/vnd.publishare-delta-tree', - 'qt' => 'video/quicktime', - 'qwd' => 'application/vnd.quark.quarkxpress', - 'qwt' => 'application/vnd.quark.quarkxpress', - 'qxb' => 'application/vnd.quark.quarkxpress', - 'qxd' => 'application/vnd.quark.quarkxpress', - 'qxl' => 'application/vnd.quark.quarkxpress', - 'qxt' => 'application/vnd.quark.quarkxpress', - 'ra' => 'audio/x-realaudio', - 'ram' => 'audio/x-pn-realaudio', - 'raml' => 'application/raml+yaml', - 'rapd' => 'application/route-apd+xml', - 'rar' => 'application/x-rar', - 'ras' => 'image/x-cmu-raster', - 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', - 'rdf' => 'application/rdf+xml', - 'rdz' => 'application/vnd.data-vision.rdz', - 'relo' => 'application/p2p-overlay+xml', - 'rep' => 'application/vnd.businessobjects', - 'res' => 'application/x-dtbresource+xml', - 'rgb' => 'image/x-rgb', - 'rif' => 'application/reginfo+xml', - 'rip' => 'audio/vnd.rip', - 'ris' => 'application/x-research-info-systems', - 'rl' => 'application/resource-lists+xml', - 'rlc' => 'image/vnd.fujixerox.edmics-rlc', - 'rld' => 'application/resource-lists-diff+xml', - 'rm' => 'audio/x-pn-realaudio', - 'rmi' => 'audio/midi', - 'rmp' => 'audio/x-pn-realaudio-plugin', - 'rms' => 'application/vnd.jcp.javame.midlet-rms', - 'rmvb' => 'application/vnd.rn-realmedia-vbr', - 'rnc' => 'application/relax-ng-compact-syntax', - 'rng' => 'application/xml', - 'roa' => 'application/rpki-roa', - 'roff' => 'text/troff', - 'rp9' => 'application/vnd.cloanto.rp9', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'rpss' => 'application/vnd.nokia.radio-presets', - 'rpst' => 'application/vnd.nokia.radio-preset', - 'rq' => 'application/sparql-query', - 'rs' => 'application/rls-services+xml', - 'rsa' => 'application/x-pkcs7', - 'rsat' => 'application/atsc-rsat+xml', - 'rsd' => 'application/rsd+xml', - 'rsheet' => 'application/urc-ressheet+xml', - 'rss' => 'application/rss+xml', - 'rtf' => 'text/rtf', - 'rtx' => 'text/richtext', - 'run' => 'application/x-makeself', - 'rusd' => 'application/route-usd+xml', - 'rv' => 'video/vnd.rn-realvideo', - 's' => 'text/x-asm', - 's3m' => 'audio/s3m', - 'saf' => 'application/vnd.yamaha.smaf-audio', - 'sass' => 'text/x-sass', - 'sbml' => 'application/sbml+xml', - 'sc' => 'application/vnd.ibm.secure-container', - 'scd' => 'application/x-msschedule', - 'scm' => 'application/vnd.lotus-screencam', - 'scq' => 'application/scvp-cv-request', - 'scs' => 'application/scvp-cv-response', - 'scss' => 'text/x-scss', - 'scurl' => 'text/vnd.curl.scurl', - 'sda' => 'application/vnd.stardivision.draw', - 'sdc' => 'application/vnd.stardivision.calc', - 'sdd' => 'application/vnd.stardivision.impress', - 'sdkd' => 'application/vnd.solent.sdkm+xml', - 'sdkm' => 'application/vnd.solent.sdkm+xml', - 'sdp' => 'application/sdp', - 'sdw' => 'application/vnd.stardivision.writer', - 'sea' => 'application/octet-stream', - 'see' => 'application/vnd.seemail', - 'seed' => 'application/vnd.fdsn.seed', - 'sema' => 'application/vnd.sema', - 'semd' => 'application/vnd.semd', - 'semf' => 'application/vnd.semf', - 'senmlx' => 'application/senml+xml', - 'sensmlx' => 'application/sensml+xml', - 'ser' => 'application/java-serialized-object', - 'setpay' => 'application/set-payment-initiation', - 'setreg' => 'application/set-registration-initiation', - 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', - 'sfs' => 'application/vnd.spotfire.sfs', - 'sfv' => 'text/x-sfv', - 'sgi' => 'image/sgi', - 'sgl' => 'application/vnd.stardivision.writer-global', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'sh' => 'application/x-sh', - 'shar' => 'application/x-shar', - 'shex' => 'text/shex', - 'shf' => 'application/shf+xml', - 'shtml' => 'text/html', - 'sid' => 'image/x-mrsid-image', - 'sieve' => 'application/sieve', - 'sig' => 'application/pgp-signature', - 'sil' => 'audio/silk', - 'silo' => 'model/mesh', - 'sis' => 'application/vnd.symbian.install', - 'sisx' => 'application/vnd.symbian.install', - 'sit' => 'application/x-stuffit', - 'sitx' => 'application/x-stuffitx', - 'siv' => 'application/sieve', - 'skd' => 'application/vnd.koan', - 'skm' => 'application/vnd.koan', - 'skp' => 'application/vnd.koan', - 'skt' => 'application/vnd.koan', - 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', - 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', - 'slim' => 'text/slim', - 'slm' => 'text/slim', - 'sls' => 'application/route-s-tsid+xml', - 'slt' => 'application/vnd.epson.salt', - 'sm' => 'application/vnd.stepmania.stepchart', - 'smf' => 'application/vnd.stardivision.math', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'smv' => 'video/x-smv', - 'smzip' => 'application/vnd.stepmania.package', - 'snd' => 'audio/basic', - 'snf' => 'application/x-font-snf', - 'so' => 'application/octet-stream', - 'spc' => 'application/x-pkcs7-certificates', - 'spdx' => 'text/spdx', - 'spf' => 'application/vnd.yamaha.smaf-phrase', - 'spl' => 'application/x-futuresplash', - 'spot' => 'text/vnd.in3d.spot', - 'spp' => 'application/scvp-vp-response', - 'spq' => 'application/scvp-vp-request', - 'spx' => 'audio/ogg', - 'sql' => 'application/x-sql', - 'src' => 'application/x-wais-source', - 'srt' => 'application/x-subrip', - 'sru' => 'application/sru+xml', - 'srx' => 'application/sparql-results+xml', - 'ssdl' => 'application/ssdl+xml', - 'sse' => 'application/vnd.kodak-descriptor', - 'ssf' => 'application/vnd.epson.ssf', - 'ssml' => 'application/ssml+xml', - 'sst' => 'application/octet-stream', - 'st' => 'application/vnd.sailingtracker.track', - 'stc' => 'application/vnd.sun.xml.calc.template', - 'std' => 'application/vnd.sun.xml.draw.template', - 'stf' => 'application/vnd.wt.stf', - 'sti' => 'application/vnd.sun.xml.impress.template', - 'stk' => 'application/hyperstudio', - 'stl' => 'model/stl', - 'stpx' => 'model/step+xml', - 'stpxz' => 'model/step-xml+zip', - 'stpz' => 'model/step+zip', - 'str' => 'application/vnd.pg.format', - 'stw' => 'application/vnd.sun.xml.writer.template', - 'styl' => 'text/stylus', - 'stylus' => 'text/stylus', - 'sub' => 'text/vnd.dvb.subtitle', - 'sus' => 'application/vnd.sus-calendar', - 'susp' => 'application/vnd.sus-calendar', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', - 'svc' => 'application/vnd.dvb.service', - 'svd' => 'application/vnd.svd', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - 'swa' => 'application/x-director', - 'swf' => 'application/x-shockwave-flash', - 'swi' => 'application/vnd.aristanetworks.swi', - 'swidtag' => 'application/swid+xml', - 'sxc' => 'application/vnd.sun.xml.calc', - 'sxd' => 'application/vnd.sun.xml.draw', - 'sxg' => 'application/vnd.sun.xml.writer.global', - 'sxi' => 'application/vnd.sun.xml.impress', - 'sxm' => 'application/vnd.sun.xml.math', - 'sxw' => 'application/vnd.sun.xml.writer', - 't' => 'text/troff', - 't3' => 'application/x-t3vm-image', - 't38' => 'image/t38', - 'taglet' => 'application/vnd.mynfc', - 'tao' => 'application/vnd.tao.intent-module-archive', - 'tap' => 'image/vnd.tencent.tap', - 'tar' => 'application/x-tar', - 'tcap' => 'application/vnd.3gpp2.tcap', - 'tcl' => 'application/x-tcl', - 'td' => 'application/urc-targetdesc+xml', - 'teacher' => 'application/vnd.smart.teacher', - 'tei' => 'application/tei+xml', - 'teicorpus' => 'application/tei+xml', - 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', - 'text' => 'text/plain', - 'tfi' => 'application/thraud+xml', - 'tfm' => 'application/x-tex-tfm', - 'tfx' => 'image/tiff-fx', - 'tga' => 'image/x-tga', - 'tgz' => 'application/x-tar', - 'thmx' => 'application/vnd.ms-officetheme', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'tk' => 'application/x-tcl', - 'tmo' => 'application/vnd.tmobile-livetv', - 'toml' => 'application/toml', - 'torrent' => 'application/x-bittorrent', - 'tpl' => 'application/vnd.groove-tool-template', - 'tpt' => 'application/vnd.trid.tpt', - 'tr' => 'text/troff', - 'tra' => 'application/vnd.trueapp', - 'trig' => 'application/trig', - 'trm' => 'application/x-msterminal', - 'ts' => 'video/mp2t', - 'tsd' => 'application/timestamped-data', - 'tsv' => 'text/tab-separated-values', - 'ttc' => 'font/collection', - 'ttf' => 'font/ttf', - 'ttl' => 'text/turtle', - 'ttml' => 'application/ttml+xml', - 'twd' => 'application/vnd.simtech-mindmapper', - 'twds' => 'application/vnd.simtech-mindmapper', - 'txd' => 'application/vnd.genomatix.tuxedo', - 'txf' => 'application/vnd.mobius.txf', - 'txt' => 'text/plain', - 'u3d' => 'model/u3d', - 'u8dsn' => 'message/global-delivery-status', - 'u8hdr' => 'message/global-headers', - 'u8mdn' => 'message/global-disposition-notification', - 'u8msg' => 'message/global', - 'u32' => 'application/x-authorware-bin', - 'ubj' => 'application/ubjson', - 'udeb' => 'application/x-debian-package', - 'ufd' => 'application/vnd.ufdl', - 'ufdl' => 'application/vnd.ufdl', - 'ulx' => 'application/x-glulx', - 'umj' => 'application/vnd.umajin', - 'unityweb' => 'application/vnd.unity', - 'uoml' => 'application/vnd.uoml+xml', - 'uri' => 'text/uri-list', - 'uris' => 'text/uri-list', - 'urls' => 'text/uri-list', - 'usdz' => 'model/vnd.usdz+zip', - 'ustar' => 'application/x-ustar', - 'utz' => 'application/vnd.uiq.theme', - 'uu' => 'text/x-uuencode', - 'uva' => 'audio/vnd.dece.audio', - 'uvd' => 'application/vnd.dece.data', - 'uvf' => 'application/vnd.dece.data', - 'uvg' => 'image/vnd.dece.graphic', - 'uvh' => 'video/vnd.dece.hd', - 'uvi' => 'image/vnd.dece.graphic', - 'uvm' => 'video/vnd.dece.mobile', - 'uvp' => 'video/vnd.dece.pd', - 'uvs' => 'video/vnd.dece.sd', - 'uvt' => 'application/vnd.dece.ttml+xml', - 'uvu' => 'video/vnd.uvvu.mp4', - 'uvv' => 'video/vnd.dece.video', - 'uvva' => 'audio/vnd.dece.audio', - 'uvvd' => 'application/vnd.dece.data', - 'uvvf' => 'application/vnd.dece.data', - 'uvvg' => 'image/vnd.dece.graphic', - 'uvvh' => 'video/vnd.dece.hd', - 'uvvi' => 'image/vnd.dece.graphic', - 'uvvm' => 'video/vnd.dece.mobile', - 'uvvp' => 'video/vnd.dece.pd', - 'uvvs' => 'video/vnd.dece.sd', - 'uvvt' => 'application/vnd.dece.ttml+xml', - 'uvvu' => 'video/vnd.uvvu.mp4', - 'uvvv' => 'video/vnd.dece.video', - 'uvvx' => 'application/vnd.dece.unspecified', - 'uvvz' => 'application/vnd.dece.zip', - 'uvx' => 'application/vnd.dece.unspecified', - 'uvz' => 'application/vnd.dece.zip', - 'vbox' => 'application/x-virtualbox-vbox', - 'vbox-extpack' => 'application/x-virtualbox-vbox-extpack', - 'vcard' => 'text/vcard', - 'vcd' => 'application/x-cdlink', - 'vcf' => 'text/x-vcard', - 'vcg' => 'application/vnd.groove-vcard', - 'vcs' => 'text/x-vcalendar', - 'vcx' => 'application/vnd.vcx', - 'vdi' => 'application/x-virtualbox-vdi', - 'vds' => 'model/vnd.sap.vds', - 'vhd' => 'application/x-virtualbox-vhd', - 'vis' => 'application/vnd.visionary', - 'viv' => 'video/vnd.vivo', - 'vlc' => 'application/videolan', - 'vmdk' => 'application/x-virtualbox-vmdk', - 'vob' => 'video/x-ms-vob', - 'vor' => 'application/vnd.stardivision.writer', - 'vox' => 'application/x-authorware-bin', - 'vrml' => 'model/vrml', - 'vsd' => 'application/vnd.visio', - 'vsf' => 'application/vnd.vsf', - 'vss' => 'application/vnd.visio', - 'vst' => 'application/vnd.visio', - 'vsw' => 'application/vnd.visio', - 'vtf' => 'image/vnd.valve.source.texture', - 'vtt' => 'text/vtt', - 'vtu' => 'model/vnd.vtu', - 'vxml' => 'application/voicexml+xml', - 'w3d' => 'application/x-director', - 'wad' => 'application/x-doom', - 'wadl' => 'application/vnd.sun.wadl+xml', - 'war' => 'application/java-archive', - 'wasm' => 'application/wasm', - 'wav' => 'audio/x-wav', - 'wax' => 'audio/x-ms-wax', - 'wbmp' => 'image/vnd.wap.wbmp', - 'wbs' => 'application/vnd.criticaltools.wbs+xml', - 'wbxml' => 'application/wbxml', - 'wcm' => 'application/vnd.ms-works', - 'wdb' => 'application/vnd.ms-works', - 'wdp' => 'image/vnd.ms-photo', - 'weba' => 'audio/webm', - 'webapp' => 'application/x-web-app-manifest+json', - 'webm' => 'video/webm', - 'webmanifest' => 'application/manifest+json', - 'webp' => 'image/webp', - 'wg' => 'application/vnd.pmi.widget', - 'wgt' => 'application/widget', - 'wif' => 'application/watcherinfo+xml', - 'wks' => 'application/vnd.ms-works', - 'wm' => 'video/x-ms-wm', - 'wma' => 'audio/x-ms-wma', - 'wmd' => 'application/x-ms-wmd', - 'wmf' => 'image/wmf', - 'wml' => 'text/vnd.wap.wml', - 'wmlc' => 'application/wmlc', - 'wmls' => 'text/vnd.wap.wmlscript', - 'wmlsc' => 'application/vnd.wap.wmlscriptc', - 'wmv' => 'video/x-ms-wmv', - 'wmx' => 'video/x-ms-wmx', - 'wmz' => 'application/x-msmetafile', - 'woff' => 'font/woff', - 'woff2' => 'font/woff2', - 'word' => 'application/msword', - 'wpd' => 'application/vnd.wordperfect', - 'wpl' => 'application/vnd.ms-wpl', - 'wps' => 'application/vnd.ms-works', - 'wqd' => 'application/vnd.wqd', - 'wri' => 'application/x-mswrite', - 'wrl' => 'model/vrml', - 'wsc' => 'message/vnd.wfa.wsc', - 'wsdl' => 'application/wsdl+xml', - 'wspolicy' => 'application/wspolicy+xml', - 'wtb' => 'application/vnd.webturbo', - 'wvx' => 'video/x-ms-wvx', - 'x3d' => 'model/x3d+xml', - 'x3db' => 'model/x3d+fastinfoset', - 'x3dbz' => 'model/x3d+binary', - 'x3dv' => 'model/x3d-vrml', - 'x3dvz' => 'model/x3d+vrml', - 'x3dz' => 'model/x3d+xml', - 'x32' => 'application/x-authorware-bin', - 'x_b' => 'model/vnd.parasolid.transmit.binary', - 'x_t' => 'model/vnd.parasolid.transmit.text', - 'xaml' => 'application/xaml+xml', - 'xap' => 'application/x-silverlight-app', - 'xar' => 'application/vnd.xara', - 'xav' => 'application/xcap-att+xml', - 'xbap' => 'application/x-ms-xbap', - 'xbd' => 'application/vnd.fujixerox.docuworks.binder', - 'xbm' => 'image/x-xbitmap', - 'xca' => 'application/xcap-caps+xml', - 'xcs' => 'application/calendar+xml', - 'xdf' => 'application/xcap-diff+xml', - 'xdm' => 'application/vnd.syncml.dm+xml', - 'xdp' => 'application/vnd.adobe.xdp+xml', - 'xdssc' => 'application/dssc+xml', - 'xdw' => 'application/vnd.fujixerox.docuworks', - 'xel' => 'application/xcap-el+xml', - 'xenc' => 'application/xenc+xml', - 'xer' => 'application/patch-ops-error+xml', - 'xfdf' => 'application/vnd.adobe.xfdf', - 'xfdl' => 'application/vnd.xfdl', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'xhvml' => 'application/xv+xml', - 'xif' => 'image/vnd.xiff', - 'xl' => 'application/excel', - 'xla' => 'application/vnd.ms-excel', - 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', - 'xlc' => 'application/vnd.ms-excel', - 'xlf' => 'application/xliff+xml', - 'xlm' => 'application/vnd.ms-excel', - 'xls' => 'application/vnd.ms-excel', - 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', - 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xlt' => 'application/vnd.ms-excel', - 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', - 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'xlw' => 'application/vnd.ms-excel', - 'xm' => 'audio/xm', - 'xml' => 'application/xml', - 'xns' => 'application/xcap-ns+xml', - 'xo' => 'application/vnd.olpc-sugar', - 'xop' => 'application/xop+xml', - 'xpi' => 'application/x-xpinstall', - 'xpl' => 'application/xproc+xml', - 'xpm' => 'image/x-xpixmap', - 'xpr' => 'application/vnd.is-xpr', - 'xps' => 'application/vnd.ms-xpsdocument', - 'xpw' => 'application/vnd.intercon.formnet', - 'xpx' => 'application/vnd.intercon.formnet', - 'xsd' => 'application/xml', - 'xsl' => 'application/xml', - 'xslt' => 'application/xslt+xml', - 'xsm' => 'application/vnd.syncml+xml', - 'xspf' => 'application/xspf+xml', - 'xul' => 'application/vnd.mozilla.xul+xml', - 'xvm' => 'application/xv+xml', - 'xvml' => 'application/xv+xml', - 'xwd' => 'image/x-xwindowdump', - 'xyz' => 'chemical/x-xyz', - 'xz' => 'application/x-xz', - 'yaml' => 'text/yaml', - 'yang' => 'application/yang', - 'yin' => 'application/yin+xml', - 'yml' => 'text/yaml', - 'ymp' => 'text/x-suse-ymp', - 'z' => 'application/x-compress', - 'z1' => 'application/x-zmachine', - 'z2' => 'application/x-zmachine', - 'z3' => 'application/x-zmachine', - 'z4' => 'application/x-zmachine', - 'z5' => 'application/x-zmachine', - 'z6' => 'application/x-zmachine', - 'z7' => 'application/x-zmachine', - 'z8' => 'application/x-zmachine', - 'zaz' => 'application/vnd.zzazz.deck+xml', - 'zip' => 'application/zip', - 'zir' => 'application/vnd.zul', - 'zirz' => 'application/vnd.zul', - 'zmm' => 'application/vnd.handheld-entertainment+xml', - 'zsh' => 'text/x-scriptzsh', - ]; - - public function lookupMimeType(string $extension): ?string - { - return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null; - } -} diff --git a/vendor/league/mime-type-detection/src/MimeTypeDetector.php b/vendor/league/mime-type-detection/src/MimeTypeDetector.php deleted file mode 100644 index 5d799d2a8..000000000 --- a/vendor/league/mime-type-detection/src/MimeTypeDetector.php +++ /dev/null @@ -1,19 +0,0 @@ - $overrides - */ - public function __construct(ExtensionToMimeTypeMap $innerMap, array $overrides) - { - $this->innerMap = $innerMap; - $this->overrides = $overrides; - } - - public function lookupMimeType(string $extension): ?string - { - return $this->overrides[$extension] ?? $this->innerMap->lookupMimeType($extension); - } -} diff --git a/vendor/phpoffice/phpspreadsheet/.php-cs-fixer.dist.php b/vendor/phpoffice/phpspreadsheet/.php-cs-fixer.dist.php index ca2feb429..16809b849 100644 --- a/vendor/phpoffice/phpspreadsheet/.php-cs-fixer.dist.php +++ b/vendor/phpoffice/phpspreadsheet/.php-cs-fixer.dist.php @@ -55,7 +55,7 @@ $config 'function_declaration' => true, 'function_to_constant' => true, 'function_typehint_space' => true, - 'general_phpdoc_annotation_remove' => ['annotations' => ['access', 'category', 'copyright', 'throws']], + 'general_phpdoc_annotation_remove' => ['annotations' => ['access', 'category', 'copyright']], 'global_namespace_import' => true, 'header_comment' => false, // We don't use common header in all our files 'heredoc_indentation' => false, // Requires PHP >= 7.3 diff --git a/vendor/phpoffice/phpspreadsheet/CHANGELOG.md b/vendor/phpoffice/phpspreadsheet/CHANGELOG.md index f820d903f..84bb504e9 100644 --- a/vendor/phpoffice/phpspreadsheet/CHANGELOG.md +++ b/vendor/phpoffice/phpspreadsheet/CHANGELOG.md @@ -5,6 +5,109 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com) and this project adheres to [Semantic Versioning](https://semver.org). +## 1.25.2 - 2022-09-25 + +### Added + +- Nothing + +### Changed + +- Nothing + +### Deprecated + +- Nothing + +### Removed + +- Nothing + +### Fixed + +- Composer dependency clash with ezyang/htmlpurifier + + +## 1.25.0 - 2022-09-25 + +### Added + +- Implementation of the new `TEXTBEFORE()`, `TEXTAFTER()` and `TEXTSPLIT()` Excel Functions +- Implementation of the `ARRAYTOTEXT()` and `VALUETOTEXT()` Excel Functions +- Support for [mitoteam/jpgraph](https://packagist.org/packages/mitoteam/jpgraph) implementation of + JpGraph library to render charts added. +- Charts: Add Gradients, Transparency, Hidden Axes, Rounded Corners, Trendlines, Date Axes. + +### Changed + +- Allow variant behaviour when merging cells [Issue #3065](https://github.com/PHPOffice/PhpSpreadsheet/issues/3065) + - Merge methods now allow an additional `$behaviour` argument. Permitted values are: + - Worksheet::MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells (the default behaviour) + - Worksheet::MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells + - Worksheet::MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell + +### Deprecated + +- Axis getLineProperty deprecated in favor of getLineColorProperty. +- Moved majorGridlines and minorGridlines from Chart to Axis. Setting either in Chart constructor or through Chart methods, or getting either using Chart methods is deprecated. +- Chart::EXCEL_COLOR_TYPE_* copied from Properties to ChartColor; use in Properties is deprecated. +- ChartColor::EXCEL_COLOR_TYPE_ARGB deprecated in favor of EXCEL_COLOR_TYPE_RGB ("A" component was never allowed). +- Misspelled Properties::LINE_STYLE_DASH_SQUERE_DOT deprecated in favor of LINE_STYLE_DASH_SQUARE_DOT. +- Clone not permitted for Spreadsheet. Spreadsheet->copy() can be used instead. + +### Removed + +- Nothing + +### Fixed + +- Fix update to defined names when inserting/deleting rows/columns [Issue #3076](https://github.com/PHPOffice/PhpSpreadsheet/issues/3076) [PR #3077](https://github.com/PHPOffice/PhpSpreadsheet/pull/3077) +- Fix DataValidation sqRef when inserting/deleting rows/columns [Issue #3056](https://github.com/PHPOffice/PhpSpreadsheet/issues/3056) [PR #3074](https://github.com/PHPOffice/PhpSpreadsheet/pull/3074) +- Named ranges not usable as anchors in OFFSET function [Issue #3013](https://github.com/PHPOffice/PhpSpreadsheet/issues/3013) +- Fully flatten an array [Issue #2955](https://github.com/PHPOffice/PhpSpreadsheet/issues/2955) [PR #2956](https://github.com/PHPOffice/PhpSpreadsheet/pull/2956) +- cellExists() and getCell() methods should support UTF-8 named cells [Issue #2987](https://github.com/PHPOffice/PhpSpreadsheet/issues/2987) [PR #2988](https://github.com/PHPOffice/PhpSpreadsheet/pull/2988) +- Spreadsheet copy fixed, clone disabled. [PR #2951](https://github.com/PHPOffice/PhpSpreadsheet/pull/2951) +- Fix PDF problems with text rotation and paper size. [Issue #1747](https://github.com/PHPOffice/PhpSpreadsheet/issues/1747) [Issue #1713](https://github.com/PHPOffice/PhpSpreadsheet/issues/1713) [PR #2960](https://github.com/PHPOffice/PhpSpreadsheet/pull/2960) +- Limited support for chart titles as formulas [Issue #2965](https://github.com/PHPOffice/PhpSpreadsheet/issues/2965) [Issue #749](https://github.com/PHPOffice/PhpSpreadsheet/issues/749) [PR #2971](https://github.com/PHPOffice/PhpSpreadsheet/pull/2971) +- Add Gradients, Transparency, and Hidden Axes to Chart [Issue #2257](https://github.com/PHPOffice/PhpSpreadsheet/issues/2257) [Issue #2229](https://github.com/PHPOffice/PhpSpreadsheet/issues/2929) [Issue #2935](https://github.com/PHPOffice/PhpSpreadsheet/issues/2935) [PR #2950](https://github.com/PHPOffice/PhpSpreadsheet/pull/2950) +- Chart Support for Rounded Corners and Trendlines [Issue #2968](https://github.com/PHPOffice/PhpSpreadsheet/issues/2968) [Issue #2815](https://github.com/PHPOffice/PhpSpreadsheet/issues/2815) [PR #2976](https://github.com/PHPOffice/PhpSpreadsheet/pull/2976) +- Add setName Method for Chart [Issue #2991](https://github.com/PHPOffice/PhpSpreadsheet/issues/2991) [PR #3001](https://github.com/PHPOffice/PhpSpreadsheet/pull/3001) +- Eliminate partial dependency on php-intl in StringHelper [Issue #2982](https://github.com/PHPOffice/PhpSpreadsheet/issues/2982) [PR #2994](https://github.com/PHPOffice/PhpSpreadsheet/pull/2994) +- Minor changes for Pdf [Issue #2999](https://github.com/PHPOffice/PhpSpreadsheet/issues/2999) [PR #3002](https://github.com/PHPOffice/PhpSpreadsheet/pull/3002) [PR #3006](https://github.com/PHPOffice/PhpSpreadsheet/pull/3006) +- Html/Pdf Do net set background color for cells using (default) nofill [PR #3016](https://github.com/PHPOffice/PhpSpreadsheet/pull/3016) +- Add support for Date Axis to Chart [Issue #2967](https://github.com/PHPOffice/PhpSpreadsheet/issues/2967) [PR #3018](https://github.com/PHPOffice/PhpSpreadsheet/pull/3018) +- Reconcile Differences Between Css and Excel for Cell Alignment [PR #3048](https://github.com/PHPOffice/PhpSpreadsheet/pull/3048) +- R1C1 Format Internationalization and Better Support for Relative Offsets [Issue #1704](https://github.com/PHPOffice/PhpSpreadsheet/issues/1704) [PR #3052](https://github.com/PHPOffice/PhpSpreadsheet/pull/3052) +- Minor Fix for Percentage Formatting [Issue #1929](https://github.com/PHPOffice/PhpSpreadsheet/issues/1929) [PR #3053](https://github.com/PHPOffice/PhpSpreadsheet/pull/3053) + +## 1.24.1 - 2022-07-18 + +### Added + +- Support for SimpleCache Interface versions 1.0, 2.0 and 3.0 +- Add Chart Axis Option textRotation [Issue #2705](https://github.com/PHPOffice/PhpSpreadsheet/issues/2705) [PR #2940](https://github.com/PHPOffice/PhpSpreadsheet/pull/2940) + +### Changed + +- Nothing + +### Deprecated + +- Nothing + +### Removed + +- Nothing + +### Fixed + +- Fix Encoding issue with Html reader (PHP 8.2 deprecation for mb_convert_encoding) [Issue #2942](https://github.com/PHPOffice/PhpSpreadsheet/issues/2942) [PR #2943](https://github.com/PHPOffice/PhpSpreadsheet/pull/2943) +- Additional Chart fixes + - Pie chart with part separated unwantedly [Issue #2506](https://github.com/PHPOffice/PhpSpreadsheet/issues/2506) [PR #2928](https://github.com/PHPOffice/PhpSpreadsheet/pull/2928) + - Chart styling is lost on simple load / save process [Issue #1797](https://github.com/PHPOffice/PhpSpreadsheet/issues/1797) [Issue #2077](https://github.com/PHPOffice/PhpSpreadsheet/issues/2077) [PR #2930](https://github.com/PHPOffice/PhpSpreadsheet/pull/2930) + - Can't create contour chart (surface 2d) [Issue #2931](https://github.com/PHPOffice/PhpSpreadsheet/issues/2931) [PR #2933](https://github.com/PHPOffice/PhpSpreadsheet/pull/2933) +- VLOOKUP Breaks When Array Contains Null Cells [Issue #2934](https://github.com/PHPOffice/PhpSpreadsheet/issues/2934) [PR #2939](https://github.com/PHPOffice/PhpSpreadsheet/pull/2939) + ## 1.24.0 - 2022-07-09 Note that this will be the last 1.x branch release before the 2.x release. We will maintain both branches in parallel for a time; but users are requested to update to version 2.0 once that is fully available. diff --git a/vendor/phpoffice/phpspreadsheet/README.md b/vendor/phpoffice/phpspreadsheet/README.md index 57560702a..ef04cd072 100644 --- a/vendor/phpoffice/phpspreadsheet/README.md +++ b/vendor/phpoffice/phpspreadsheet/README.md @@ -29,7 +29,7 @@ composer require phpoffice/phpspreadsheet ``` If you are building your installation on a development machine that is on a different PHP version to the server where it will be deployed, or if your PHP CLI version is not the same as your run-time such as `php-fpm` or Apache's `mod_php`, then you might want to add the following to your `composer.json` before installing: -```json lines +```json { "require": { "phpoffice/phpspreadsheet": "^1.23" @@ -71,15 +71,19 @@ or the appropriate PDF Writer wrapper for the library that you have chosen to in #### Chart Export -For Chart export, we support, which you will also need to install yourself - - jpgraph/jpgraph +For Chart export, we support following packages, which you will also need to install yourself using `composer require` + - [jpgraph/jpgraph](https://packagist.org/packages/jpgraph/jpgraph) (this package was abandoned at version 4.0. + You can manually download the latest version that supports PHP 8 and above from [jpgraph.net](https://jpgraph.net/)) + - [mitoteam/jpgraph](https://packagist.org/packages/mitoteam/jpgraph) (fork with php 8.1 support) and then configure PhpSpreadsheet using: ```php -Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); +Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); // to use jpgraph/jpgraph +//or +Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class); // to use mitoteam/jpgraph ``` -You can `composer/require` the github version of jpgraph, but this was abandoned at version 4.0; or manually download the latest version that supports PHP 8 and above from [jpgraph.net](https://jpgraph.net/) +One or the other of these libraries is necessary if you want to generate HTML or PDF files that include charts. ## Documentation diff --git a/vendor/phpoffice/phpspreadsheet/composer.json b/vendor/phpoffice/phpspreadsheet/composer.json index 16991514f..e686788eb 100644 --- a/vendor/phpoffice/phpspreadsheet/composer.json +++ b/vendor/phpoffice/phpspreadsheet/composer.json @@ -69,32 +69,33 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.13", + "ezyang/htmlpurifier": "^4.15", "maennchen/zipstream-php": "^2.1", "markbaker/complex": "^3.0", "markbaker/matrix": "^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/simple-cache": "^1.0 || ^2.0" + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-master", "dompdf/dompdf": "^1.0 || ^2.0", "friendsofphp/php-cs-fixer": "^3.2", - "jpgraph/jpgraph": "^4.0", + "mitoteam/jpgraph": "10.2.4", "mpdf/mpdf": "8.1.1", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.7", - "tecnickcom/tcpdf": "^6.4" + "tecnickcom/tcpdf": "6.5" }, "suggest": { + "ext-intl": "PHP Internationalization Functions", "mpdf/mpdf": "Option for rendering PDF with PDF Writer", - "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", - "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", - "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers" + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers" }, "autoload": { "psr-4": { diff --git a/vendor/phpoffice/phpspreadsheet/phpstan-baseline.neon b/vendor/phpoffice/phpspreadsheet/phpstan-baseline.neon index 5ef5522f0..c4b76cdd7 100644 --- a/vendor/phpoffice/phpspreadsheet/phpstan-baseline.neon +++ b/vendor/phpoffice/phpspreadsheet/phpstan-baseline.neon @@ -515,11 +515,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/FormulaParser.php - - - message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/FormulaParser.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:ifCondition\\(\\) has no return type specified\\.$#" count: 1 @@ -1065,11 +1060,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/TextData/Text.php - - - message: "#^Elseif branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:getFormulaAttributes\\(\\) has no return type specified\\.$#" count: 1 @@ -1110,11 +1100,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Coordinate.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Memory\\:\\:\\$cache has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Collection/Memory.php - - message: "#^Parameter \\#1 \\$namedRange of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:addNamedRange\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\NamedRange, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\) given\\.$#" count: 1 @@ -1675,456 +1660,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls/RC4.php - - - message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot access offset 0 on array\\\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Cannot access property \\$r on SimpleXMLElement\\|null\\.$#" count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Cannot call method addChart\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Comparison operation \"\\>\" between SimpleXMLElement\\|null and 0 results in an error\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:boolean\\(\\) has parameter \\$value with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToBoolean\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToBoolean\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToError\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToError\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$calculatedValue with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$castBaseType with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$cellDataType with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$r with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$sharedFormulas with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$value with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToString\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToString\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has parameter \\$add with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has parameter \\$base with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has parameter \\$array with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has parameter \\$key with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getFromZipArchive\\(\\) should return string but returns string\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$dir with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$docSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$fileWorksheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$dir with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$docSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$fileWorksheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:stripWhiteSpaceFromStyleString\\(\\) has parameter \\$string with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:toCSSArray\\(\\) has parameter \\$style with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Negated boolean expression is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$fontSizeInPoints of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:fontSizeToPixels\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, int\\|string given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$sizeInCm of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:centimeterSizeToPixels\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$sizeInInch of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:inchSizeToPixels\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, array\\|string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, int\\|string given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$autoFilterRange with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$xmlSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Parameter \\#1 \\$operator of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:setRule\\(\\) expects string, null given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\BaseParserClass\\:\\:boolean\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\BaseParserClass\\:\\:boolean\\(\\) has parameter \\$value with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredColumn\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredColumn\\(\\) has parameter \\$columnCoordinate with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredRow\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredRow\\(\\) has parameter \\$rowCoordinate with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnAttributes\\(\\) has parameter \\$readDataOnly with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnRangeAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnRangeAttributes\\(\\) has parameter \\$readDataOnly with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readRowAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readRowAttributes\\(\\) has parameter \\$readDataOnly with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readConditionalStyles\\(\\) has parameter \\$xmlSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarExtLstOfConditionalRule\\(\\) has parameter \\$cfRule with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarExtLstOfConditionalRule\\(\\) has parameter \\$conditionalFormattingRuleExtensions with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarOfConditionalRule\\(\\) has parameter \\$cfRule with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarOfConditionalRule\\(\\) has parameter \\$conditionalFormattingRuleExtensions with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has parameter \\$cfRules with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has parameter \\$extLst with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:setConditionalStyles\\(\\) has parameter \\$xmlExtLst with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$dxfs has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\DataValidations\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\DataValidations\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:\\$hyperlinks has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:load\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:pageSetup\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViewOptions\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViewOptions\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, string\\|false given\\.$#" count: 1 @@ -2270,51 +1810,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE.php - - - message: "#^Cannot access offset 0 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Cannot access offset 2 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Cannot access offset 4 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Cannot access offset 6 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Parameter \\#1 \\$size of function imagettfbbox expects float, float\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Parameter \\#2 \\$defaultFont of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Drawing\\:\\:pixelsToCellDimension\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:\\$autoSizeMethods has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - - - message: "#^Variable \\$cellText on left side of \\?\\? always exists and is not nullable\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Font.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\EigenvalueDecomposition\\:\\:\\$cdivi has no type specified\\.$#" count: 1 @@ -2335,11 +1830,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php - - - message: "#^Call to function is_string\\(\\) with float\\|int will always evaluate to false\\.$#" - count: 5 - path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:__construct\\(\\) has parameter \\$args with no type specified\\.$#" count: 1 @@ -2420,11 +1910,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php - - - message: "#^Result of && is always false\\.$#" - count: 10 - path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php - - message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 19 @@ -2860,11 +2345,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Comparison operation \"\\<\\=\" between int\\ and 1000 is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - message: "#^Parameter \\#1 \\$worksheet of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getIndex\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet, PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null given\\.$#" count: 1 @@ -2875,21 +2355,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Result of \\|\\| is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet and null will always evaluate to false\\.$#" count: 1 path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 @@ -3125,21 +2595,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Worksheet/PageSetup.php - - - message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\PageSetup\\:\\:setFirstPageNumber\\(\\) expects int, null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\PageSetup\\:\\:\\$pageOrder has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/PageSetup.php - - - - message: "#^Strict comparison using \\=\\=\\= between int\\ and null will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/PageSetup.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\SheetView\\:\\:\\$sheetViewTypes has no type specified\\.$#" count: 1 @@ -3240,316 +2695,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - - message: "#^Call to function array_key_exists\\(\\) with int and array\\{none\\: 'none', dashDot\\: '1px dashed', dashDotDot\\: '1px dotted', dashed\\: '1px dashed', dotted\\: '1px dotted', double\\: '3px double', hair\\: '1px solid', medium\\: '2px solid', \\.\\.\\.\\} will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Cannot access offset 'mime' on array\\|false\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Cannot access offset 0 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Cannot access offset 1 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Cannot call method getSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Cannot call method getSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:calculateSpansOmitRows\\(\\) has parameter \\$candidateSpannedRow with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:calculateSpansOmitRows\\(\\) has parameter \\$sheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:calculateSpansOmitRows\\(\\) has parameter \\$sheetIndex with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateHTMLFooter\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateMeta\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateMeta\\(\\) has parameter \\$desc with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateMeta\\(\\) has parameter \\$val with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$cellAddress with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$columnNumber with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$row with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$cell with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$cellType with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$cssClass with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValue\\(\\) has parameter \\$cell with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValue\\(\\) has parameter \\$cellData with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValueRich\\(\\) has parameter \\$cell with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValueRich\\(\\) has parameter \\$cellData with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowIncludeCharts\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowIncludeCharts\\(\\) has parameter \\$coordinate with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has parameter \\$colSpan with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has parameter \\$html with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has parameter \\$rowSpan with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$cellData with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$cellType with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$colNum with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$colSpan with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$coordinate with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$cssClass with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$html with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$row with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$rowSpan with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$sheetIndex with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetPrep\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetStarts\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetStarts\\(\\) has parameter \\$rowMin with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetStarts\\(\\) has parameter \\$sheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$row with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$tbodyStart with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$theadEnd with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$theadStart with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableFooter\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$html with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$id with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$sheetIndex with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTagInline\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTagInline\\(\\) has parameter \\$id with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Parameter \\#1 \\$borderStyle of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapBorderStyle\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Parameter \\#1 \\$font of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:createCSSStyleFont\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Parameter \\#1 \\$hAlign of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapHAlign\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Parameter \\#1 \\$vAlign of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapVAlign\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Parameter \\#2 \\$length of function fread expects int\\<0, max\\>, int\\<0, max\\>\\|false given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - - - message: "#^Parameter \\#3 \\$use_include_path of function fopen expects bool, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Html.php - - message: "#^Negated boolean expression is always false\\.$#" count: 1 @@ -3772,7 +2917,7 @@ parameters: - message: "#^Cannot access offset 1 on array\\|false\\.$#" - count: 2 + count: 1 path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php - @@ -3869,289 +3014,3 @@ parameters: message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:\\$diag is never read, only written\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xls/Xf.php - - - - message: "#^Argument of an invalid type array\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Parameter \\#1 \\$path of function basename expects string, array\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Parameter \\#1 \\$path of function dirname expects string, array\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Possibly invalid array key type array\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\:\\:\\$pathNames has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Parameter \\#1 \\$string of function substr expects string, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php - - - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php - - - - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php - - - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$relationship with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$type with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Parameter \\#2 \\$id of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects int, string given\\.$#" - count: 5 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Parameter \\#4 \\$target of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects string, array\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Cannot call method getBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Instanceof between \\*NEVER\\* and PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Instanceof between string and PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#1 \\$text of method PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText\\:\\:createTextRun\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#" - count: 4 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getStyle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Conditional\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Comparison operation \"\\<\" between int\\ and 0 is always true\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$borders of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeBorder\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Borders, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Borders\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$fill of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeFill\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$font of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeFont\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$numberFormat of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeNumFmt\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 22 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<1, max\\> given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#" - count: 7 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Result of \\|\\| is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 7 - path: src/PhpSpreadsheet/Writer/Xlsx/Workbook.php - - - - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^If condition is always true\\.$#" - count: 6 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeAttributeIf\\(\\) has parameter \\$condition with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeDataBarElements\\(\\) has parameter \\$dataBar with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeElementIf\\(\\) has parameter \\$condition with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int\\|string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 15 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<1, max\\> given\\.$#" - count: 9 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#3 \\$stringTable of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeSheetData\\(\\) expects array\\, array\\\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#4 \\$val of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeAttributeIf\\(\\) expects string, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - diff --git a/vendor/phpoffice/phpspreadsheet/phpstan.neon.dist b/vendor/phpoffice/phpspreadsheet/phpstan.neon.dist index 61672b28c..30bd6c2f7 100644 --- a/vendor/phpoffice/phpspreadsheet/phpstan.neon.dist +++ b/vendor/phpoffice/phpspreadsheet/phpstan.neon.dist @@ -11,17 +11,13 @@ parameters: - tests/ excludePaths: - src/PhpSpreadsheet/Chart/Renderer/JpGraph.php + - src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php parallel: processTimeout: 300.0 checkMissingIterableValueType: false ignoreErrors: - - '~^Parameter \#1 \$im(age)? of function (imagedestroy|imageistruecolor|imagealphablending|imagesavealpha|imagecolortransparent|imagecolorsforindex|imagesavealpha|imagesx|imagesy) expects (GdImage|resource), GdImage\|resource given\.$~' + - '~^Parameter \#1 \$im(age)? of function (imagedestroy|imageistruecolor|imagealphablending|imagesavealpha|imagecolortransparent|imagecolorsforindex|imagesavealpha|imagesx|imagesy|imagepng) expects (GdImage|resource), GdImage\|resource given\.$~' - '~^Parameter \#2 \$src_im(age)? of function imagecopy expects (GdImage|resource), GdImage\|resource given\.$~' # Accept a bit anything for assert methods - '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~' - '~^Method PhpOffice\\PhpSpreadsheetTests\\.*\:\:test.*\(\) has parameter \$args with no type specified\.$~' - - # Some issues in Xls/Parser between 1.6.3 and 1.7.7 - - - message: "#^Offset '(left|right|value)' does not exist on (non-empty-array\\|string|array\\|null)\\.$#" - path: src/PhpSpreadsheet/Writer/Xls/Parser.php diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php index 5b1c55202..4f95af54f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php @@ -7,7 +7,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Engine\CyclicReferenceStack; use PhpOffice\PhpSpreadsheet\Calculation\Engine\Logger; use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; -use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; use PhpOffice\PhpSpreadsheet\Calculation\Token\Stack; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; @@ -305,8 +304,8 @@ class Calculation ], 'ARRAYTOTEXT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', + 'functionCall' => [TextData\Text::class, 'fromArray'], + 'argumentCount' => '1,2', ], 'ASC' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, @@ -2490,13 +2489,13 @@ class Calculation ], 'TEXTAFTER' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-4', + 'functionCall' => [TextData\Extract::class, 'after'], + 'argumentCount' => '2-6', ], 'TEXTBEFORE' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-4', + 'functionCall' => [TextData\Extract::class, 'before'], + 'argumentCount' => '2-6', ], 'TEXTJOIN' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, @@ -2505,8 +2504,8 @@ class Calculation ], 'TEXTSPLIT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2-5', + 'functionCall' => [TextData\Text::class, 'split'], + 'argumentCount' => '2-6', ], 'THAIDAYOFWEEK' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, @@ -2660,8 +2659,8 @@ class Calculation ], 'VALUETOTEXT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '?', + 'functionCall' => [TextData\Format::class, 'valueToText'], + 'argumentCount' => '1,2', ], 'VAR' => [ 'category' => Category::CATEGORY_STATISTICAL, @@ -3111,7 +3110,7 @@ class Calculation [$localeFunction] = explode('##', $localeFunction); // Strip out comments if (strpos($localeFunction, '=') !== false) { [$fName, $lfName] = array_map('trim', explode('=', $localeFunction)); - if ((isset(self::$phpSpreadsheetFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { + if ((substr($fName, 0, 1) === '*' || isset(self::$phpSpreadsheetFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { self::$localeFunctions[$fName] = $lfName; } } @@ -4757,9 +4756,8 @@ class Calculation break; } - - // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on } elseif (($token === '~') || ($token === '%')) { + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on if (($arg = $stack->pop()) === null) { return $this->raiseFormulaError('Internal error - Operand value missing from stack'); } @@ -4795,7 +4793,7 @@ class Calculation if (isset($matches[8])) { if ($cell === null) { - // We can't access the range, so return a REF error + // We can't access the range, so return a REF error $cellValue = Information\ExcelError::REF(); } else { $cellRef = $matches[6] . $matches[7] . ':' . $matches[9] . $matches[10]; @@ -4866,9 +4864,8 @@ class Calculation if (isset($storeKey)) { $branchStore[$storeKey] = $cellValue; } - - // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on } elseif (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $token ?? '', $matches)) { + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on if ($pCellParent) { $cell->attach($pCellParent); } @@ -4978,8 +4975,8 @@ class Calculation if (isset($storeKey)) { $branchStore[$storeKey] = $token; } - // if the token is a named range or formula, evaluate it and push the result onto the stack } elseif (preg_match('/^' . self::CALCULATION_REGEXP_DEFINEDNAME . '$/miu', $token, $matches)) { + // if the token is a named range or formula, evaluate it and push the result onto the stack $definedName = $matches[6]; if ($cell === null || $pCellWorksheet === null) { return $this->raiseFormulaError("undefined name '$token'"); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php index c6ee5969e..256c3effb 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/Logger.php @@ -98,9 +98,9 @@ class Logger $cellReference = implode(' -> ', $this->cellStack->showStack()); if ($this->echoDebugLog) { echo $cellReference, - ($this->cellStack->count() > 0 ? ' => ' : ''), - $message, - PHP_EOL; + ($this->cellStack->count() > 0 ? ' => ' : ''), + $message, + PHP_EOL; } $this->debugLog[] = $cellReference . ($this->cellStack->count() > 0 ? ' => ' : '') . diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php index 4d4bc07e3..6aaf1faa5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/Compare.php @@ -57,7 +57,7 @@ class Compare * * @param array|float $number the value to test against step * Or can be an array of values - * @param array|float $step The threshold value. If you omit a value for step, GESTEP uses zero. + * @param null|array|float $step The threshold value. If you omit a value for step, GESTEP uses zero. * Or can be an array of values * * @return array|int|string (string in the event of an error) @@ -72,7 +72,7 @@ class Compare try { $number = EngineeringValidations::validateFloat($number); - $step = EngineeringValidations::validateFloat($step); + $step = EngineeringValidations::validateFloat($step ?? 0.0); } catch (Exception $e) { return $e->getMessage(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php index 677fb0fb7..b7c298dbc 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php @@ -106,6 +106,7 @@ class ConvertUOM 'W' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Watt', 'AllowPrefix' => true], 'w' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Watt', 'AllowPrefix' => true], 'PS' => ['Group' => self::CATEGORY_POWER, 'Unit Name' => 'Pferdestärke', 'AllowPrefix' => false], + // Magnetism 'T' => ['Group' => self::CATEGORY_MAGNETISM, 'Unit Name' => 'Tesla', 'AllowPrefix' => true], 'ga' => ['Group' => self::CATEGORY_MAGNETISM, 'Unit Name' => 'Gauss', 'AllowPrefix' => true], // Temperature diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/FormulaParser.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/FormulaParser.php index ddf45b23b..f71d96fc7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/FormulaParser.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/FormulaParser.php @@ -61,7 +61,7 @@ class FormulaParser /** * Create a new FormulaParser. * - * @param string $formula Formula to parse + * @param ?string $formula Formula to parse */ public function __construct($formula = '') { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php index ddd3e200a..172f20222 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php @@ -573,24 +573,20 @@ class Functions return (array) $array; } - $arrayValues = []; - foreach ($array as $value) { + $flattened = []; + $stack = array_values($array); + + while ($stack) { + $value = array_shift($stack); + if (is_array($value)) { - foreach ($value as $val) { - if (is_array($val)) { - foreach ($val as $v) { - $arrayValues[] = $v; - } - } else { - $arrayValues[] = $val; - } - } + array_unshift($stack, ...array_values($value)); } else { - $arrayValues[] = $value; + $flattened[] = $value; } } - return $arrayValues; + return $flattened; } /** @@ -691,7 +687,7 @@ class Functions $worksheet2 = $defined->getWorkSheet(); if (!$defined->isFormula() && $worksheet2 !== null) { $coordinate = "'" . $worksheet2->getTitle() . "'!" . - (string) preg_replace('/^=/', '', $defined->getValue()); + (string) preg_replace('/^=/', '', str_replace('$', '', $defined->getValue())); } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php index dda2c7050..4b9f818fe 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php @@ -47,7 +47,7 @@ class ErrorValue return false; } - return in_array($value, ExcelError::$errorCodes, true); + return in_array($value, ExcelError::ERROR_CODES, true); } /** diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php index 5ca74a3ed..06f386635 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/ExcelError.php @@ -13,7 +13,7 @@ class ExcelError * * @var array */ - public static $errorCodes = [ + public const ERROR_CODES = [ 'null' => '#NULL!', // 1 'divisionbyzero' => '#DIV/0!', // 2 'value' => '#VALUE!', // 3 @@ -30,12 +30,23 @@ class ExcelError 'calculation' => '#CALC!', //14 ]; + /** + * List of error codes. Replaced by constant; + * previously it was public and updateable, allowing + * user to make inappropriate alterations. + * + * @deprecated 1.25.0 Use ERROR_CODES constant instead. + * + * @var array + */ + public static $errorCodes = self::ERROR_CODES; + /** * @param mixed $value */ public static function throwError($value): string { - return in_array($value, self::$errorCodes, true) ? $value : self::$errorCodes['value']; + return in_array($value, self::ERROR_CODES, true) ? $value : self::ERROR_CODES['value']; } /** @@ -52,7 +63,7 @@ class ExcelError } $i = 1; - foreach (self::$errorCodes as $errorCode) { + foreach (self::ERROR_CODES as $errorCode) { if ($value === $errorCode) { return $i; } @@ -71,7 +82,7 @@ class ExcelError */ public static function null(): string { - return self::$errorCodes['null']; + return self::ERROR_CODES['null']; } /** @@ -83,7 +94,7 @@ class ExcelError */ public static function NAN(): string { - return self::$errorCodes['num']; + return self::ERROR_CODES['num']; } /** @@ -95,7 +106,7 @@ class ExcelError */ public static function REF(): string { - return self::$errorCodes['reference']; + return self::ERROR_CODES['reference']; } /** @@ -111,7 +122,7 @@ class ExcelError */ public static function NA(): string { - return self::$errorCodes['na']; + return self::ERROR_CODES['na']; } /** @@ -123,7 +134,7 @@ class ExcelError */ public static function VALUE(): string { - return self::$errorCodes['value']; + return self::ERROR_CODES['value']; } /** @@ -135,7 +146,7 @@ class ExcelError */ public static function NAME(): string { - return self::$errorCodes['name']; + return self::ERROR_CODES['name']; } /** @@ -145,7 +156,7 @@ class ExcelError */ public static function DIV0(): string { - return self::$errorCodes['divisionbyzero']; + return self::ERROR_CODES['divisionbyzero']; } /** @@ -155,6 +166,6 @@ class ExcelError */ public static function CALC(): string { - return self::$errorCodes['calculation']; + return self::ERROR_CODES['calculation']; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php index 0ac6b6697..2e524db53 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Information/Value.php @@ -240,7 +240,7 @@ class Value * * @param null|mixed $value The value you want converted * - * @return number N converts values listed in the following table + * @return number|string N converts values listed in the following table * If value is or refers to N returns * A number That number value * A date The Excel serialized number of that date diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php index c8cdf2dd8..0d2db8b20 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Address.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Cell\AddressHelper; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; class Address @@ -72,6 +73,9 @@ class Address $sheetName = self::sheetName($sheetName); + if (is_int($referenceStyle)) { + $referenceStyle = (bool) $referenceStyle; + } if ((!is_bool($referenceStyle)) || $referenceStyle === self::REFERENCE_STYLE_A1) { return self::formatAsA1($row, $column, $relativity, $sheetName); } @@ -113,7 +117,8 @@ class Address if (($relativity == self::ADDRESS_ROW_RELATIVE) || ($relativity == self::ADDRESS_RELATIVE)) { $row = "[{$row}]"; } + [$rowChar, $colChar] = AddressHelper::getRowAndColumnChars(); - return "{$sheetName}R{$row}C{$column}"; + return "{$sheetName}$rowChar{$row}$colChar{$column}"; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php index d67718ce0..e2d27bde2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php @@ -66,7 +66,7 @@ class HLookup extends LookupBase */ private static function hLookupSearch($lookupValue, array $lookupArray, $column, bool $notExactMatch): ?int { - $lookupLower = StringHelper::strToLower($lookupValue); + $lookupLower = StringHelper::strToLower((string) $lookupValue); $rowNumber = null; foreach ($lookupArray[$column] as $rowKey => $rowData) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php index 7408a66e8..76a194b38 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php @@ -13,12 +13,12 @@ class Helpers public const CELLADDRESS_USE_R1C1 = false; - private static function convertR1C1(string &$cellAddress1, ?string &$cellAddress2, bool $a1): string + private static function convertR1C1(string &$cellAddress1, ?string &$cellAddress2, bool $a1, ?int $baseRow = null, ?int $baseCol = null): string { if ($a1 === self::CELLADDRESS_USE_R1C1) { - $cellAddress1 = AddressHelper::convertToA1($cellAddress1); + $cellAddress1 = AddressHelper::convertToA1($cellAddress1, $baseRow ?? 1, $baseCol ?? 1); if ($cellAddress2) { - $cellAddress2 = AddressHelper::convertToA1($cellAddress2); + $cellAddress2 = AddressHelper::convertToA1($cellAddress2, $baseRow ?? 1, $baseCol ?? 1); } } @@ -35,7 +35,7 @@ class Helpers } } - public static function extractCellAddresses(string $cellAddress, bool $a1, Worksheet $sheet, string $sheetName = ''): array + public static function extractCellAddresses(string $cellAddress, bool $a1, Worksheet $sheet, string $sheetName = '', ?int $baseRow = null, ?int $baseCol = null): array { $cellAddress1 = $cellAddress; $cellAddress2 = null; @@ -52,7 +52,7 @@ class Helpers if (strpos($cellAddress, ':') !== false) { [$cellAddress1, $cellAddress2] = explode(':', $cellAddress); } - $cellAddress = self::convertR1C1($cellAddress1, $cellAddress2, $a1); + $cellAddress = self::convertR1C1($cellAddress1, $cellAddress2, $a1, $baseRow, $baseCol); return [$cellAddress1, $cellAddress2, $cellAddress]; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php index 417a1f798..91a14491e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php @@ -7,6 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Indirect @@ -63,6 +64,8 @@ class Indirect */ public static function INDIRECT($cellAddress, $a1fmt, Cell $cell) { + [$baseCol, $baseRow] = Coordinate::indexesFromString($cell->getCoordinate()); + try { $a1 = self::a1Format($a1fmt); $cellAddress = self::validateAddress($cellAddress); @@ -78,7 +81,11 @@ class Indirect $cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress)); } - [$cellAddress1, $cellAddress2, $cellAddress] = Helpers::extractCellAddresses($cellAddress, $a1, $cell->getWorkSheet(), $sheetName); + try { + [$cellAddress1, $cellAddress2, $cellAddress] = Helpers::extractCellAddresses($cellAddress, $a1, $cell->getWorkSheet(), $sheetName, $baseRow, $baseCol); + } catch (Exception $e) { + return ExcelError::REF(); + } if ( (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress1, $matches)) || diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php index 8e451fe41..a001540c2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php @@ -19,8 +19,16 @@ abstract class LookupBase protected static function validateIndexLookup(array $lookup_array, $index_number): int { - // index_number must be a number greater than or equal to 1 - if (!is_numeric($index_number) || $index_number < 1) { + // index_number must be a number greater than or equal to 1. + // Excel results are inconsistent when index is non-numeric. + // VLOOKUP(whatever, whatever, SQRT(-1)) yields NUM error, but + // VLOOKUP(whatever, whatever, cellref) yields REF error + // when cellref is '=SQRT(-1)'. So just try our best here. + // Similar results if string (literal yields VALUE, cellRef REF). + if (!is_numeric($index_number)) { + throw new Exception(ExcelError::throwError($index_number)); + } + if ($index_number < 1) { throw new Exception(ExcelError::VALUE()); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php index 9f3377f6d..02a255812 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php @@ -99,6 +99,8 @@ class Offset private static function extractWorksheet($cellAddress, Cell $cell): array { + $cellAddress = self::assessCellAddress($cellAddress, $cell); + $sheetName = ''; if (strpos($cellAddress, '!') !== false) { [$sheetName, $cellAddress] = Worksheet::extractSheetTitle($cellAddress, true); @@ -112,6 +114,15 @@ class Offset return [$cellAddress, $worksheet]; } + private static function assessCellAddress(string $cellAddress, Cell $cell): string + { + if (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/mui', $cellAddress) !== false) { + $cellAddress = Functions::expandDefinedName($cellAddress, $cell); + } + + return $cellAddress; + } + private static function adjustEndCellColumnForWidth(string $endCellColumn, $width, int $startCellColumn, $columns) { $endCellColumn = Coordinate::columnIndexFromString($endCellColumn) - 1; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php index 53a7badc9..edeb1aa8c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php @@ -68,8 +68,8 @@ class VLookup extends LookupBase { reset($a); $firstColumn = key($a); - $aLower = StringHelper::strToLower($a[$firstColumn]); - $bLower = StringHelper::strToLower($b[$firstColumn]); + $aLower = StringHelper::strToLower((string) $a[$firstColumn]); + $bLower = StringHelper::strToLower((string) $b[$firstColumn]); if ($aLower == $bLower) { return 0; @@ -84,7 +84,7 @@ class VLookup extends LookupBase */ private static function vLookupSearch($lookupValue, array $lookupArray, $column, bool $notExactMatch): ?int { - $lookupLower = StringHelper::strToLower($lookupValue); + $lookupLower = StringHelper::strToLower((string) $lookupValue); $rowNumber = null; foreach ($lookupArray as $rowKey => $rowData) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php index b9fcfc73e..22cad2cfd 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig/Random.php @@ -17,7 +17,7 @@ class Random */ public static function rand() { - return (mt_rand(0, 10000000)) / 10000000; + return mt_rand(0, 10000000) / 10000000; } /** diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php index 41b011a5f..85195c88f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Averages.php @@ -203,7 +203,7 @@ class Averages extends AggregateBase $args, function ($value) { // Is it a numeric value? - return (is_numeric($value)) && (!is_string($value)); + return is_numeric($value) && (!is_string($value)); } ); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php index 8574d58db..c87433648 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php @@ -101,7 +101,7 @@ class ChiSquared return 1 - self::distributionRightTail($value, $degrees); } - return (($value ** (($degrees / 2) - 1) * exp(-$value / 2))) / + return ($value ** (($degrees / 2) - 1) * exp(-$value / 2)) / ((2 ** ($degrees / 2)) * Gamma::gammaValue($degrees / 2)); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php index d29f80cab..ee7e31b77 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Extract.php @@ -4,6 +4,9 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; +use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class Extract { @@ -95,4 +98,183 @@ class Extract return mb_substr($value ?? '', mb_strlen($value ?? '', 'UTF-8') - $chars, $chars, 'UTF-8'); } + + /** + * TEXTBEFORE. + * + * @param mixed $text the text that you're searching + * Or can be an array of values + * @param null|array|string $delimiter the text that marks the point before which you want to extract + * Multiple delimiters can be passed as an array of string values + * @param mixed $instance The instance of the delimiter after which you want to extract the text. + * By default, this is the first instance (1). + * A negative value means start searching from the end of the text string. + * Or can be an array of values + * @param mixed $matchMode Determines whether the match is case-sensitive or not. + * 0 - Case-sensitive + * 1 - Case-insensitive + * Or can be an array of values + * @param mixed $matchEnd Treats the end of text as a delimiter. + * 0 - Don't match the delimiter against the end of the text. + * 1 - Match the delimiter against the end of the text. + * Or can be an array of values + * @param mixed $ifNotFound value to return if no match is found + * The default is a #N/A Error + * Or can be an array of values + * + * @return mixed|mixed[] the string extracted from text before the delimiter; or the $ifNotFound value + * If an array of values is passed for any of the arguments, then the returned result + * will also be an array with matching dimensions + */ + public static function before($text, $delimiter, $instance = 1, $matchMode = 0, $matchEnd = 0, $ifNotFound = '#N/A') + { + if (is_array($text) || is_array($instance) || is_array($matchMode) || is_array($matchEnd) || is_array($ifNotFound)) { + return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); + } + + $text = Helpers::extractString($text ?? ''); + $instance = (int) $instance; + $matchMode = (int) $matchMode; + $matchEnd = (int) $matchEnd; + + $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); + if (is_array($split) === false) { + return $split; + } + if (Helpers::extractString(Functions::flattenSingleValue($delimiter ?? '')) === '') { + return ($instance > 0) ? '' : $text; + } + + // Adjustment for a match as the first element of the split + $flags = self::matchFlags($matchMode); + $delimiter = self::buildDelimiter($delimiter); + $adjust = preg_match('/^' . $delimiter . "\$/{$flags}", $split[0]); + $oddReverseAdjustment = count($split) % 2; + + $split = ($instance < 0) + ? array_slice($split, 0, max(count($split) - (abs($instance) * 2 - 1) - $adjust - $oddReverseAdjustment, 0)) + : array_slice($split, 0, $instance * 2 - 1 - $adjust); + + return implode('', $split); + } + + /** + * TEXTAFTER. + * + * @param mixed $text the text that you're searching + * @param null|array|string $delimiter the text that marks the point before which you want to extract + * Multiple delimiters can be passed as an array of string values + * @param mixed $instance The instance of the delimiter after which you want to extract the text. + * By default, this is the first instance (1). + * A negative value means start searching from the end of the text string. + * Or can be an array of values + * @param mixed $matchMode Determines whether the match is case-sensitive or not. + * 0 - Case-sensitive + * 1 - Case-insensitive + * Or can be an array of values + * @param mixed $matchEnd Treats the end of text as a delimiter. + * 0 - Don't match the delimiter against the end of the text. + * 1 - Match the delimiter against the end of the text. + * Or can be an array of values + * @param mixed $ifNotFound value to return if no match is found + * The default is a #N/A Error + * Or can be an array of values + * + * @return mixed|mixed[] the string extracted from text before the delimiter; or the $ifNotFound value + * If an array of values is passed for any of the arguments, then the returned result + * will also be an array with matching dimensions + */ + public static function after($text, $delimiter, $instance = 1, $matchMode = 0, $matchEnd = 0, $ifNotFound = '#N/A') + { + if (is_array($text) || is_array($instance) || is_array($matchMode) || is_array($matchEnd) || is_array($ifNotFound)) { + return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); + } + + $text = Helpers::extractString($text ?? ''); + $instance = (int) $instance; + $matchMode = (int) $matchMode; + $matchEnd = (int) $matchEnd; + + $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); + if (is_array($split) === false) { + return $split; + } + if (Helpers::extractString(Functions::flattenSingleValue($delimiter ?? '')) === '') { + return ($instance < 0) ? '' : $text; + } + + // Adjustment for a match as the first element of the split + $flags = self::matchFlags($matchMode); + $delimiter = self::buildDelimiter($delimiter); + $adjust = preg_match('/^' . $delimiter . "\$/{$flags}", $split[0]); + $oddReverseAdjustment = count($split) % 2; + + $split = ($instance < 0) + ? array_slice($split, count($split) - (abs($instance + 1) * 2) - $adjust - $oddReverseAdjustment) + : array_slice($split, $instance * 2 - $adjust); + + return implode('', $split); + } + + /** + * @param null|array|string $delimiter + * @param int $matchMode + * @param int $matchEnd + * @param mixed $ifNotFound + * + * @return string|string[] + */ + private static function validateTextBeforeAfter(string $text, $delimiter, int $instance, $matchMode, $matchEnd, $ifNotFound) + { + $flags = self::matchFlags($matchMode); + $delimiter = self::buildDelimiter($delimiter); + + if (preg_match('/' . $delimiter . "/{$flags}", $text) === 0 && $matchEnd === 0) { + return $ifNotFound; + } + + $split = preg_split('/' . $delimiter . "/{$flags}", $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); + if ($split === false) { + return ExcelError::NA(); + } + + if ($instance === 0 || abs($instance) > StringHelper::countCharacters($text)) { + return ExcelError::VALUE(); + } + + if ($matchEnd === 0 && (abs($instance) > floor(count($split) / 2))) { + return ExcelError::NA(); + } elseif ($matchEnd !== 0 && (abs($instance) - 1 > ceil(count($split) / 2))) { + return ExcelError::NA(); + } + + return $split; + } + + /** + * @param null|array|string $delimiter the text that marks the point before which you want to extract + * Multiple delimiters can be passed as an array of string values + */ + private static function buildDelimiter($delimiter): string + { + if (is_array($delimiter)) { + $delimiter = Functions::flattenArray($delimiter); + $quotedDelimiters = array_map( + function ($delimiter) { + return preg_quote($delimiter ?? ''); + }, + $delimiter + ); + $delimiters = implode('|', $quotedDelimiters); + + return '(' . $delimiters . ')'; + } + + return '(' . preg_quote($delimiter ?? '') . ')'; + } + + private static function matchFlags(int $matchMode): string + { + return ($matchMode === 0) ? 'mu' : 'miu'; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php index bec114968..03e75d1d2 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Format.php @@ -4,11 +4,13 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use DateTimeInterface; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; @@ -208,6 +210,38 @@ class Format return (float) $value; } + /** + * TEXT. + * + * @param mixed $value The value to format + * Or can be an array of values + * @param mixed $format + * + * @return array|string + * If an array of values is passed for either of the arguments, then the returned result + * will also be an array with matching dimensions + */ + public static function valueToText($value, $format = false) + { + if (is_array($value) || is_array($format)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $format); + } + + $format = (bool) $format; + + if (is_object($value) && $value instanceof RichText) { + $value = $value->getPlainText(); + } + if (is_string($value)) { + $value = ($format === true) ? Calculation::wrapResult($value) : $value; + $value = str_replace("\n", '', $value); + } elseif (is_bool($value)) { + $value = Calculation::$localeBoolean[$value === true ? 'TRUE' : 'FALSE']; + } + + return (string) $value; + } + /** * @param mixed $decimalSeparator */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php index 490c43c20..83810422c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData/Text.php @@ -3,6 +3,8 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\TextData; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Text { @@ -77,4 +79,176 @@ class Text return null; } + + /** + * TEXTSPLIT. + * + * @param mixed $text the text that you're searching + * @param null|array|string $columnDelimiter The text that marks the point where to spill the text across columns. + * Multiple delimiters can be passed as an array of string values + * @param null|array|string $rowDelimiter The text that marks the point where to spill the text down rows. + * Multiple delimiters can be passed as an array of string values + * @param bool $ignoreEmpty Specify FALSE to create an empty cell when two delimiters are consecutive. + * true = create empty cells + * false = skip empty cells + * Defaults to TRUE, which creates an empty cell + * @param bool $matchMode Determines whether the match is case-sensitive or not. + * true = case-sensitive + * false = case-insensitive + * By default, a case-sensitive match is done. + * @param mixed $padding The value with which to pad the result. + * The default is #N/A. + * + * @return array the array built from the text, split by the row and column delimiters + */ + public static function split($text, $columnDelimiter = null, $rowDelimiter = null, bool $ignoreEmpty = false, bool $matchMode = true, $padding = '#N/A') + { + $text = Functions::flattenSingleValue($text); + + $flags = self::matchFlags($matchMode); + + if ($rowDelimiter !== null) { + $delimiter = self::buildDelimiter($rowDelimiter); + $rows = ($delimiter === '()') + ? [$text] + : preg_split("/{$delimiter}/{$flags}", $text); + } else { + $rows = [$text]; + } + + /** @var array $rows */ + if ($ignoreEmpty === true) { + $rows = array_values(array_filter( + $rows, + function ($row) { + return $row !== ''; + } + )); + } + + if ($columnDelimiter !== null) { + $delimiter = self::buildDelimiter($columnDelimiter); + array_walk( + $rows, + function (&$row) use ($delimiter, $flags, $ignoreEmpty): void { + $row = ($delimiter === '()') + ? [$row] + : preg_split("/{$delimiter}/{$flags}", $row); + /** @var array $row */ + if ($ignoreEmpty === true) { + $row = array_values(array_filter( + $row, + function ($value) { + return $value !== ''; + } + )); + } + } + ); + if ($ignoreEmpty === true) { + $rows = array_values(array_filter( + $rows, + function ($row) { + return $row !== [] && $row !== ['']; + } + )); + } + } + + return self::applyPadding($rows, $padding); + } + + /** + * @param mixed $padding + */ + private static function applyPadding(array $rows, $padding): array + { + $columnCount = array_reduce( + $rows, + function (int $counter, array $row): int { + return max($counter, count($row)); + }, + 0 + ); + + return array_map( + function (array $row) use ($columnCount, $padding): array { + return (count($row) < $columnCount) + ? array_merge($row, array_fill(0, $columnCount - count($row), $padding)) + : $row; + }, + $rows + ); + } + + /** + * @param null|array|string $delimiter the text that marks the point before which you want to split + * Multiple delimiters can be passed as an array of string values + */ + private static function buildDelimiter($delimiter): string + { + $valueSet = Functions::flattenArray($delimiter); + + if (is_array($delimiter) && count($valueSet) > 1) { + $quotedDelimiters = array_map( + function ($delimiter) { + return preg_quote($delimiter ?? ''); + }, + $valueSet + ); + $delimiters = implode('|', $quotedDelimiters); + + return '(' . $delimiters . ')'; + } + + return '(' . preg_quote(Functions::flattenSingleValue($delimiter)) . ')'; + } + + private static function matchFlags(bool $matchMode): string + { + return ($matchMode === true) ? 'miu' : 'mu'; + } + + public static function fromArray(array $array, int $format = 0): string + { + $result = []; + foreach ($array as $row) { + $cells = []; + foreach ($row as $cellValue) { + $value = ($format === 1) ? self::formatValueMode1($cellValue) : self::formatValueMode0($cellValue); + $cells[] = $value; + } + $result[] = implode(($format === 1) ? ',' : ', ', $cells); + } + + $result = implode(($format === 1) ? ';' : ', ', $result); + + return ($format === 1) ? '{' . $result . '}' : $result; + } + + /** + * @param mixed $cellValue + */ + private static function formatValueMode0($cellValue): string + { + if (is_bool($cellValue)) { + return ($cellValue) ? Calculation::$localeBoolean['TRUE'] : Calculation::$localeBoolean['FALSE']; + } + + return (string) $cellValue; + } + + /** + * @param mixed $cellValue + */ + private static function formatValueMode1($cellValue): string + { + if (is_string($cellValue) && Functions::isError($cellValue) === false) { + return Calculation::FORMULA_STRING_QUOTE . $cellValue . Calculation::FORMULA_STRING_QUOTE; + } elseif (is_bool($cellValue)) { + return ($cellValue) ? Calculation::$localeBoolean['TRUE'] : Calculation::$localeBoolean['FALSE']; + } + + return (string) $cellValue; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/Translations.xlsx b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/locale/Translations.xlsx index d013aee0f1a2dea934a0a215e5aaa1e3202bbecb..7b9fb0dddfff921e9831507af3b0dfd53a8ee10a 100644 GIT binary patch delta 97055 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 z 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 aY;M+8O0usI{{4An delta 96406 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

kRS+FJs>|j1s|SB3^yySfvWerv?)OThZcTsFcT| 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 = $value; @@ -111,7 +110,7 @@ class Cell $dataType = DataType::TYPE_STRING; } $this->dataType = $dataType; - } elseif (!self::getValueBinder()->bindValue($this, $value)) { + } elseif (self::getValueBinder()->bindValue($this, $value) === false) { throw new Exception('Value could not be bound to cell.'); } } @@ -167,10 +166,8 @@ class Cell /** * Get cell value with formatting. - * - * @return string */ - public function getFormattedValue() + public function getFormattedValue(): string { return (string) NumberFormat::toFormattedString( $this->getCalculatedValue(), @@ -188,7 +185,7 @@ class Cell * * @return $this */ - public function setValue($value) + public function setValue($value): self { if (!self::getValueBinder()->bindValue($this, $value)) { throw new Exception('Value could not be bound to cell.'); @@ -205,7 +202,7 @@ class Cell * Note that PhpSpreadsheet does not validate that the value and datatype are consistent, in using this * method, then it is your responsibility as an end-user developer to validate that the value and * the datatype match. - * If you do mismatch value and datatpe, then the value you enter may be changed to match the datatype + * If you do mismatch value and datatype, then the value you enter may be changed to match the datatype * that you specify. * * @return Cell @@ -271,7 +268,7 @@ class Cell * * @return mixed */ - public function getCalculatedValue($resetLog = true) + public function getCalculatedValue(bool $resetLog = true) { if ($this->dataType === DataType::TYPE_FORMULA) { try { @@ -316,10 +313,8 @@ class Cell * Set old calculated value (cached). * * @param mixed $originalValue Value - * - * @return Cell */ - public function setCalculatedValue($originalValue) + public function setCalculatedValue($originalValue): self { if ($originalValue !== null) { $this->calculatedValue = (is_numeric($originalValue)) ? (float) $originalValue : $originalValue; @@ -345,10 +340,8 @@ class Cell /** * Get cell data type. - * - * @return string */ - public function getDataType() + public function getDataType(): string { return $this->dataType; } @@ -357,10 +350,8 @@ class Cell * Set cell data type. * * @param string $dataType see DataType::TYPE_* - * - * @return Cell */ - public function setDataType($dataType) + public function setDataType($dataType): self { if ($dataType == DataType::TYPE_STRING2) { $dataType = DataType::TYPE_STRING; @@ -392,10 +383,8 @@ class Cell /** * Get Data validation rules. - * - * @return DataValidation */ - public function getDataValidation() + public function getDataValidation(): DataValidation { if (!isset($this->parent)) { throw new Exception('Cannot get data validation for cell that is not bound to a worksheet'); @@ -420,10 +409,8 @@ class Cell /** * Does this cell contain valid value? - * - * @return bool */ - public function hasValidValue() + public function hasValidValue(): bool { $validator = new DataValidator(); @@ -432,10 +419,8 @@ class Cell /** * Does this cell contain a Hyperlink? - * - * @return bool */ - public function hasHyperlink() + public function hasHyperlink(): bool { if (!isset($this->parent)) { throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); @@ -446,10 +431,8 @@ class Cell /** * Get Hyperlink. - * - * @return Hyperlink */ - public function getHyperlink() + public function getHyperlink(): Hyperlink { if (!isset($this->parent)) { throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); @@ -460,10 +443,8 @@ class Cell /** * Set Hyperlink. - * - * @return Cell */ - public function setHyperlink(?Hyperlink $hyperlink = null) + public function setHyperlink(?Hyperlink $hyperlink = null): self { if (!isset($this->parent)) { throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); @@ -486,10 +467,8 @@ class Cell /** * Get parent worksheet. - * - * @return Worksheet */ - public function getWorksheet() + public function getWorksheet(): Worksheet { try { $worksheet = $this->parent->getParent(); @@ -506,27 +485,22 @@ class Cell /** * Is this cell in a merge range. - * - * @return bool */ - public function isInMergeRange() + public function isInMergeRange(): bool { return (bool) $this->getMergeRange(); } /** * Is this cell the master (top left cell) in a merge range (that holds the actual data value). - * - * @return bool */ - public function isMergeRangeValueCell() + public function isMergeRangeValueCell(): bool { if ($mergeRange = $this->getMergeRange()) { $mergeRange = Coordinate::splitRange($mergeRange); [$startCell] = $mergeRange[0]; - if ($this->getCoordinate() === $startCell) { - return true; - } + + return $this->getCoordinate() === $startCell; } return false; @@ -576,10 +550,8 @@ class Cell /** * Re-bind parent. - * - * @return Cell */ - public function rebindParent(Worksheet $parent) + public function rebindParent(Worksheet $parent): self { $this->parent = $parent->getCellCollection(); @@ -590,10 +562,8 @@ class Cell * Is cell in a specific range? * * @param string $range Cell range (e.g. A1:A1) - * - * @return bool */ - public function isInRange($range) + public function isInRange(string $range): bool { [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($range); @@ -614,7 +584,7 @@ class Cell * * @return int Result of comparison (always -1 or 1, never zero!) */ - public static function compareCells(self $a, self $b) + public static function compareCells(self $a, self $b): int { if ($a->getRow() < $b->getRow()) { return -1; @@ -629,10 +599,8 @@ class Cell /** * Get value binder to use. - * - * @return IValueBinder */ - public static function getValueBinder() + public static function getValueBinder(): IValueBinder { if (self::$valueBinder === null) { self::$valueBinder = new DefaultValueBinder(); @@ -655,33 +623,27 @@ class Cell public function __clone() { $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if ((is_object($value)) && ($key != 'parent')) { - $this->$key = clone $value; + foreach ($vars as $propertyName => $propertyValue) { + if ((is_object($propertyValue)) && ($propertyName !== 'parent')) { + $this->$propertyName = clone $propertyValue; } else { - $this->$key = $value; + $this->$propertyName = $propertyValue; } } } /** * Get index to cellXf. - * - * @return int */ - public function getXfIndex() + public function getXfIndex(): int { return $this->xfIndex; } /** * Set index to cellXf. - * - * @param int $indexValue - * - * @return Cell */ - public function setXfIndex($indexValue) + public function setXfIndex(int $indexValue): self { $this->xfIndex = $indexValue; @@ -695,7 +657,7 @@ class Cell * * @return $this */ - public function setFormulaAttributes($attributes) + public function setFormulaAttributes($attributes): self { $this->formulaAttributes = $attributes; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php index 506783979..2fca62127 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Cell; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; @@ -349,6 +350,19 @@ abstract class Coordinate */ public static function extractAllCellReferencesInRange($cellRange): array { + if (substr_count($cellRange, '!') > 1) { + throw new Exception('3-D Range References are not supported'); + } + + [$worksheet, $cellRange] = Worksheet::extractSheetTitle($cellRange, true); + $quoted = ''; + if ($worksheet > '') { + $quoted = Worksheet::nameRequiresQuotes($worksheet) ? "'" : ''; + if (substr($worksheet, 0, 1) === "'" && substr($worksheet, -1, 1) === "'") { + $worksheet = substr($worksheet, 1, -1); + } + $worksheet = str_replace("'", "''", $worksheet); + } [$ranges, $operators] = self::getCellBlocksFromRangeString($cellRange); $cells = []; @@ -364,7 +378,12 @@ abstract class Coordinate $cellList = array_merge(...$cells); - return self::sortCellReferenceArray($cellList); + return array_map( + function ($cellAddress) use ($worksheet, $quoted) { + return ($worksheet !== '') ? "{$quoted}{$worksheet}{$quoted}!{$cellAddress}" : $cellAddress; + }, + self::sortCellReferenceArray($cellList) + ); } private static function processRangeSetOperators(array $operators, array $cells): array diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Axis.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Axis.php index 1f55cf03b..9ebb081fa 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Axis.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Axis.php @@ -10,6 +10,14 @@ namespace PhpOffice\PhpSpreadsheet\Chart; */ class Axis extends Properties { + const AXIS_TYPE_CATEGORY = 'catAx'; + const AXIS_TYPE_DATE = 'dateAx'; + const AXIS_TYPE_VALUE = 'valAx'; + + const TIME_UNIT_DAYS = 'days'; + const TIME_UNIT_MONTHS = 'months'; + const TIME_UNIT_YEARS = 'years'; + public function __construct() { parent::__construct(); @@ -60,6 +68,11 @@ class Axis extends Properties 'axis_labels' => self::AXIS_LABELS_NEXT_TO, 'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO, 'horizontal_crosses_value' => null, + 'textRotation' => null, + 'hidden' => null, + 'majorTimeUnit' => self::TIME_UNIT_YEARS, + 'minorTimeUnit' => self::TIME_UNIT_MONTHS, + 'baseTimeUnit' => self::TIME_UNIT_DAYS, ]; /** @@ -72,6 +85,7 @@ class Axis extends Properties private const NUMERIC_FORMAT = [ Properties::FORMAT_CODE_NUMBER, Properties::FORMAT_CODE_DATE, + Properties::FORMAT_CODE_DATE_ISO8601, ]; /** @@ -113,12 +127,12 @@ class Axis extends Properties public function getAxisIsNumericFormat(): bool { - return (bool) $this->axisNumber['numeric']; + return $this->axisType === self::AXIS_TYPE_DATE || (bool) $this->axisNumber['numeric']; } public function setAxisOption(string $key, ?string $value): void { - if (!empty($value)) { + if ($value !== null && $value !== '') { $this->axisOptions[$key] = $value; } } @@ -136,7 +150,12 @@ class Axis extends Properties ?string $minimum = null, ?string $maximum = null, ?string $majorUnit = null, - ?string $minorUnit = null + ?string $minorUnit = null, + ?string $textRotation = null, + ?string $hidden = null, + ?string $baseTimeUnit = null, + ?string $majorTimeUnit = null, + ?string $minorTimeUnit = null ): void { $this->axisOptions['axis_labels'] = $axisLabels; $this->setAxisOption('horizontal_crosses_value', $horizontalCrossesValue); @@ -144,11 +163,15 @@ class Axis extends Properties $this->setAxisOption('orientation', $axisOrientation); $this->setAxisOption('major_tick_mark', $majorTmt); $this->setAxisOption('minor_tick_mark', $minorTmt); - $this->setAxisOption('minor_tick_mark', $minorTmt); $this->setAxisOption('minimum', $minimum); $this->setAxisOption('maximum', $maximum); $this->setAxisOption('major_unit', $majorUnit); $this->setAxisOption('minor_unit', $minorUnit); + $this->setAxisOption('textRotation', $textRotation); + $this->setAxisOption('hidden', $hidden); + $this->setAxisOption('baseTimeUnit', $baseTimeUnit); + $this->setAxisOption('majorTimeUnit', $majorTimeUnit); + $this->setAxisOption('minorTimeUnit', $minorTimeUnit); } /** @@ -180,7 +203,7 @@ class Axis extends Properties public function setAxisType(string $type): self { - if ($type === 'catAx' || $type === 'valAx') { + if ($type === self::AXIS_TYPE_CATEGORY || $type === self::AXIS_TYPE_VALUE || $type === self::AXIS_TYPE_DATE) { $this->axisType = $type; } else { $this->axisType = ''; @@ -196,7 +219,7 @@ class Axis extends Properties * @param ?int $alpha * @param ?string $AlphaType */ - public function setFillParameters($color, $alpha = null, $AlphaType = self::EXCEL_COLOR_TYPE_ARGB): void + public function setFillParameters($color, $alpha = null, $AlphaType = ChartColor::EXCEL_COLOR_TYPE_RGB): void { $this->fillColor->setColorProperties($color, $alpha, $AlphaType); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php index 3f4dd2a7f..f41d78830 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Chart.php @@ -141,6 +141,15 @@ class Chart /** @var bool */ private $oneCellAnchor = false; + /** @var bool */ + private $autoTitleDeleted = false; + + /** @var bool */ + private $noFill = false; + + /** @var bool */ + private $roundedCorners = false; + /** * Create a new Chart. * majorGridlines and minorGridlines are deprecated, moved to Axis. @@ -179,6 +188,13 @@ class Chart return $this->name; } + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + /** * Get Worksheet. */ @@ -645,14 +661,10 @@ class Chart /** * Render the chart to given file (or stream). - * Unable to cover code until a usable current version of JpGraph - * is made available through Composer. * * @param string $outputDestination Name of the file render to * * @return bool true on success - * - * @codeCoverageIgnore */ public function render($outputDestination = null) { @@ -732,4 +744,42 @@ class Chart return $this; } + + public function getAutoTitleDeleted(): bool + { + return $this->autoTitleDeleted; + } + + public function setAutoTitleDeleted(bool $autoTitleDeleted): self + { + $this->autoTitleDeleted = $autoTitleDeleted; + + return $this; + } + + public function getNoFill(): bool + { + return $this->noFill; + } + + public function setNoFill(bool $noFill): self + { + $this->noFill = $noFill; + + return $this; + } + + public function getRoundedCorners(): bool + { + return $this->roundedCorners; + } + + public function setRoundedCorners(?bool $roundedCorners): self + { + if ($roundedCorners !== null) { + $this->roundedCorners = $roundedCorners; + } + + return $this; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php index 7f87e3912..87f310200 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/ChartColor.php @@ -24,15 +24,18 @@ class ChartColor /** @var ?int */ private $alpha; + /** @var ?int */ + private $brightness; + /** * @param string|string[] $value */ - public function __construct($value = '', ?int $alpha = null, ?string $type = null) + public function __construct($value = '', ?int $alpha = null, ?string $type = null, ?int $brightness = null) { if (is_array($value)) { $this->setColorPropertiesArray($value); } else { - $this->setColorProperties($value, $alpha, $type); + $this->setColorProperties($value, $alpha, $type, $brightness); } } @@ -72,10 +75,23 @@ class ChartColor return $this; } + public function getBrightness(): ?int + { + return $this->brightness; + } + + public function setBrightness(?int $brightness): self + { + $this->brightness = $brightness; + + return $this; + } + /** * @param null|float|int|string $alpha + * @param null|float|int|string $brightness */ - public function setColorProperties(?string $color, $alpha = null, ?string $type = null): self + public function setColorProperties(?string $color, $alpha = null, ?string $type = null, $brightness = null): self { if (empty($type) && !empty($color)) { if (substr($color, 0, 1) === '*') { @@ -99,6 +115,11 @@ class ChartColor } elseif (is_numeric($alpha)) { $this->setAlpha((int) $alpha); } + if ($brightness === null) { + $this->setBrightness(null); + } elseif (is_numeric($brightness)) { + $this->setBrightness((int) $brightness); + } return $this; } @@ -108,7 +129,8 @@ class ChartColor return $this->setColorProperties( $color['value'] ?? '', $color['alpha'] ?? null, - $color['type'] ?? null + $color['type'] ?? null, + $color['brightness'] ?? null ); } @@ -133,6 +155,8 @@ class ChartColor $retVal = $this->type; } elseif ($propertyName === 'alpha') { $retVal = $this->alpha; + } elseif ($propertyName === 'brightness') { + $retVal = $this->brightness; } return $retVal; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php index 548145e7e..5d33e96d0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php @@ -94,7 +94,7 @@ class DataSeries private $plotCategory = []; /** - * Smooth Line. + * Smooth Line. Must be specified for both DataSeries and DataSeriesValues. * * @var bool */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php index bc0e04d19..cd166b23b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php @@ -88,6 +88,9 @@ class DataSeriesValues extends Properties /** @var ?Layout */ private $labelLayout; + /** @var TrendLine[] */ + private $trendLines = []; + /** * Create a new DataSeriesValues object. * @@ -321,13 +324,13 @@ class DataSeriesValues extends Properties if (is_array($this->fillColor)) { $array = []; foreach ($this->fillColor as $chartColor) { - $array[] = self::chartColorToString($chartColor); + $array[] = $this->chartColorToString($chartColor); } return $array; } - return self::chartColorToString($this->fillColor); + return $this->chartColorToString($this->fillColor); } /** @@ -345,13 +348,13 @@ class DataSeriesValues extends Properties if ($fillString instanceof ChartColor) { $this->fillColor[] = $fillString; } else { - $this->fillColor[] = self::stringToChartColor($fillString); + $this->fillColor[] = $this->stringToChartColor($fillString); } } } elseif ($color instanceof ChartColor) { $this->fillColor = $color; - } elseif (is_string($color)) { - $this->fillColor = self::stringToChartColor($color); + } else { + $this->fillColor = $this->stringToChartColor($color); } return $this; @@ -536,7 +539,7 @@ class DataSeriesValues extends Properties } /** - * Smooth Line. + * Smooth Line. Must be specified for both DataSeries and DataSeriesValues. * * @var bool */ @@ -577,4 +580,16 @@ class DataSeriesValues extends Properties return $this; } + + public function setTrendLines(array $trendLines): self + { + $this->trendLines = $trendLines; + + return $this; + } + + public function getTrendLines(): array + { + return $this->trendLines; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php index 03a0ca3ec..3dabcc63f 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Layout.php @@ -53,6 +53,19 @@ class Layout */ private $height; + /** + * Position - t=top. + * + * @var string + */ + private $dLblPos = ''; + + /** @var string */ + private $numFmtCode = ''; + + /** @var bool */ + private $numFmtLinked = false; + /** * show legend key * Specifies that legend keys should be shown in data labels. @@ -143,6 +156,12 @@ class Layout if (isset($layout['h'])) { $this->height = (float) $layout['h']; } + if (isset($layout['dLblPos'])) { + $this->dLblPos = (string) $layout['dLblPos']; + } + if (isset($layout['numFmtCode'])) { + $this->numFmtCode = (string) $layout['numFmtCode']; + } $this->initBoolean($layout, 'showLegendKey'); $this->initBoolean($layout, 'showVal'); $this->initBoolean($layout, 'showCatName'); @@ -150,6 +169,7 @@ class Layout $this->initBoolean($layout, 'showPercent'); $this->initBoolean($layout, 'showBubbleSize'); $this->initBoolean($layout, 'showLeaderLines'); + $this->initBoolean($layout, 'numFmtLinked'); $this->initColor($layout, 'labelFillColor'); $this->initColor($layout, 'labelBorderColor'); $this->initColor($layout, 'labelFontColor'); @@ -484,4 +504,40 @@ class Layout return $this; } + + public function getDLblPos(): string + { + return $this->dLblPos; + } + + public function setDLblPos(string $dLblPos): self + { + $this->dLblPos = $dLblPos; + + return $this; + } + + public function getNumFmtCode(): string + { + return $this->numFmtCode; + } + + public function setNumFmtCode(string $numFmtCode): self + { + $this->numFmtCode = $numFmtCode; + + return $this; + } + + public function getNumFmtLinked(): bool + { + return $this->numFmtLinked; + } + + public function setNumFmtLinked(bool $numFmtLinked): self + { + $this->numFmtLinked = $numFmtLinked; + + return $this; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php index 4bd49ece0..ccde4bb2a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/PlotArea.php @@ -6,6 +6,30 @@ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class PlotArea { + /** + * No fill in plot area (show Excel gridlines through chart). + * + * @var bool + */ + private $noFill = false; + + /** + * PlotArea Gradient Stop list. + * Each entry is a 2-element array. + * First is position in %. + * Second is ChartColor. + * + * @var array[] + */ + private $gradientFillStops = []; + + /** + * PlotArea Gradient Angle. + * + * @var ?float + */ + private $gradientFillAngle; + /** * PlotArea Layout. * @@ -101,4 +125,42 @@ class PlotArea $plotSeries->refresh($worksheet); } } + + public function setNoFill(bool $noFill): self + { + $this->noFill = $noFill; + + return $this; + } + + public function getNoFill(): bool + { + return $this->noFill; + } + + public function setGradientFillProperties(array $gradientFillStops, ?float $gradientFillAngle): self + { + $this->gradientFillStops = $gradientFillStops; + $this->gradientFillAngle = $gradientFillAngle; + + return $this; + } + + /** + * Get gradientFillAngle. + */ + public function getGradientFillAngle(): ?float + { + return $this->gradientFillAngle; + } + + /** + * Get gradientFillStops. + * + * @return array + */ + public function getGradientFillStops() + { + return $this->gradientFillStops; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php index b276707dd..0b0164b4e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php @@ -2,68 +2,20 @@ namespace PhpOffice\PhpSpreadsheet\Chart\Renderer; -use AccBarPlot; -use AccLinePlot; -use BarPlot; -use ContourPlot; -use Graph; -use GroupBarPlot; -use LinePlot; -use PhpOffice\PhpSpreadsheet\Chart\Chart; -use PhpOffice\PhpSpreadsheet\Style\NumberFormat; -use PieGraph; -use PiePlot; -use PiePlot3D; -use PiePlotC; -use RadarGraph; -use RadarPlot; -use ScatterPlot; -use Spline; -use StockPlot; - /** - * Jpgraph is not maintained in Composer, and the version there - * is extremely out of date. For that reason, all unit test - * requiring Jpgraph are skipped. So, do not measure - * code coverage for this class till that is fixed. + * Jpgraph is not oficially maintained in Composer, so the version there + * could be out of date. For that reason, all unit test requiring Jpgraph + * are skipped. So, do not measure code coverage for this class till that + * is fixed. + * + * This implementation uses abandoned package + * https://packagist.org/packages/jpgraph/jpgraph * * @codeCoverageIgnore */ -class JpGraph implements IRenderer +class JpGraph extends JpGraphRendererBase { - private static $width = 640; - - private static $height = 480; - - private static $colourSet = [ - 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', - 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', - 'mediumblue', 'magenta', 'sandybrown', 'cyan', - 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', - 'goldenrod2', - ]; - - private static $markSet; - - private $chart; - - private $graph; - - private static $plotColour = 0; - - private static $plotMark = 0; - - /** - * Create a new jpgraph. - */ - public function __construct(Chart $chart) - { - self::init(); - $this->graph = null; - $this->chart = $chart; - } - - private static function init(): void + protected static function init(): void { static $loaded = false; if ($loaded) { @@ -81,802 +33,6 @@ class JpGraph implements IRenderer \JpGraph\JpGraph::module('scatter'); \JpGraph\JpGraph::module('stock'); - self::$markSet = [ - 'diamond' => MARK_DIAMOND, - 'square' => MARK_SQUARE, - 'triangle' => MARK_UTRIANGLE, - 'x' => MARK_X, - 'star' => MARK_STAR, - 'dot' => MARK_FILLEDCIRCLE, - 'dash' => MARK_DTRIANGLE, - 'circle' => MARK_CIRCLE, - 'plus' => MARK_CROSS, - ]; - $loaded = true; } - - private function formatPointMarker($seriesPlot, $markerID) - { - $plotMarkKeys = array_keys(self::$markSet); - if ($markerID === null) { - // Use default plot marker (next marker in the series) - self::$plotMark %= count(self::$markSet); - $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); - } elseif ($markerID !== 'none') { - // Use specified plot marker (if it exists) - if (isset(self::$markSet[$markerID])) { - $seriesPlot->mark->SetType(self::$markSet[$markerID]); - } else { - // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) - self::$plotMark %= count(self::$markSet); - $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); - } - } else { - // Hide plot marker - $seriesPlot->mark->Hide(); - } - $seriesPlot->mark->SetColor(self::$colourSet[self::$plotColour]); - $seriesPlot->mark->SetFillColor(self::$colourSet[self::$plotColour]); - $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); - - return $seriesPlot; - } - - private function formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') - { - $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); - if ($datasetLabelFormatCode !== null) { - // Retrieve any label formatting code - $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); - } - - $testCurrentIndex = 0; - foreach ($datasetLabels as $i => $datasetLabel) { - if (is_array($datasetLabel)) { - if ($rotation == 'bar') { - $datasetLabels[$i] = implode(' ', $datasetLabel); - } else { - $datasetLabel = array_reverse($datasetLabel); - $datasetLabels[$i] = implode("\n", $datasetLabel); - } - } else { - // Format labels according to any formatting code - if ($datasetLabelFormatCode !== null) { - $datasetLabels[$i] = NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); - } - } - ++$testCurrentIndex; - } - - return $datasetLabels; - } - - private function percentageSumCalculation($groupID, $seriesCount) - { - $sumValues = []; - // Adjust our values to a percentage value across all series in the group - for ($i = 0; $i < $seriesCount; ++$i) { - if ($i == 0) { - $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - } else { - $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - foreach ($nextValues as $k => $value) { - if (isset($sumValues[$k])) { - $sumValues[$k] += $value; - } else { - $sumValues[$k] = $value; - } - } - } - } - - return $sumValues; - } - - private function percentageAdjustValues($dataValues, $sumValues) - { - foreach ($dataValues as $k => $dataValue) { - $dataValues[$k] = $dataValue / $sumValues[$k] * 100; - } - - return $dataValues; - } - - private function getCaption($captionElement) - { - // Read any caption - $caption = ($captionElement !== null) ? $captionElement->getCaption() : null; - // Test if we have a title caption to display - if ($caption !== null) { - // If we do, it could be a plain string or an array - if (is_array($caption)) { - // Implode an array to a plain string - $caption = implode('', $caption); - } - } - - return $caption; - } - - private function renderTitle(): void - { - $title = $this->getCaption($this->chart->getTitle()); - if ($title !== null) { - $this->graph->title->Set($title); - } - } - - private function renderLegend(): void - { - $legend = $this->chart->getLegend(); - if ($legend !== null) { - $legendPosition = $legend->getPosition(); - switch ($legendPosition) { - case 'r': - $this->graph->legend->SetPos(0.01, 0.5, 'right', 'center'); // right - $this->graph->legend->SetColumns(1); - - break; - case 'l': - $this->graph->legend->SetPos(0.01, 0.5, 'left', 'center'); // left - $this->graph->legend->SetColumns(1); - - break; - case 't': - $this->graph->legend->SetPos(0.5, 0.01, 'center', 'top'); // top - - break; - case 'b': - $this->graph->legend->SetPos(0.5, 0.99, 'center', 'bottom'); // bottom - - break; - default: - $this->graph->legend->SetPos(0.01, 0.01, 'right', 'top'); // top-right - $this->graph->legend->SetColumns(1); - - break; - } - } else { - $this->graph->legend->Hide(); - } - } - - private function renderCartesianPlotArea($type = 'textlin'): void - { - $this->graph = new Graph(self::$width, self::$height); - $this->graph->SetScale($type); - - $this->renderTitle(); - - // Rotate for bar rather than column chart - $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); - $reverse = $rotation == 'bar'; - - $xAxisLabel = $this->chart->getXAxisLabel(); - if ($xAxisLabel !== null) { - $title = $this->getCaption($xAxisLabel); - if ($title !== null) { - $this->graph->xaxis->SetTitle($title, 'center'); - $this->graph->xaxis->title->SetMargin(35); - if ($reverse) { - $this->graph->xaxis->title->SetAngle(90); - $this->graph->xaxis->title->SetMargin(90); - } - } - } - - $yAxisLabel = $this->chart->getYAxisLabel(); - if ($yAxisLabel !== null) { - $title = $this->getCaption($yAxisLabel); - if ($title !== null) { - $this->graph->yaxis->SetTitle($title, 'center'); - if ($reverse) { - $this->graph->yaxis->title->SetAngle(0); - $this->graph->yaxis->title->SetMargin(-55); - } - } - } - } - - private function renderPiePlotArea(): void - { - $this->graph = new PieGraph(self::$width, self::$height); - - $this->renderTitle(); - } - - private function renderRadarPlotArea(): void - { - $this->graph = new RadarGraph(self::$width, self::$height); - $this->graph->SetScale('lin'); - - $this->renderTitle(); - } - - private function renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d'): void - { - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - - $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->graph->xaxis->SetTickLabels($datasetLabels); - } - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = []; - if ($grouping == 'percentStacked') { - $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); - } else { - $sumValues = []; - } - - // Loop through each data series in turn - for ($i = 0; $i < $seriesCount; ++$i) { - $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - - if ($grouping == 'percentStacked') { - $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); - } - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach ($dataValues as $k => $dataValue) { - while ($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - $seriesPlot = new LinePlot($dataValues); - if ($combination) { - $seriesPlot->SetBarCenter(); - } - - if ($filled) { - $seriesPlot->SetFilled(true); - $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); - } else { - // Set the appropriate plot marker - $this->formatPointMarker($seriesPlot, $marker); - } - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetLegend($dataLabel); - - $seriesPlots[] = $seriesPlot; - } - - if ($grouping == 'standard') { - $groupPlot = $seriesPlots; - } else { - $groupPlot = new AccLinePlot($seriesPlots); - } - $this->graph->Add($groupPlot); - } - - private function renderPlotBar($groupID, $dimensions = '2d'): void - { - $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); - // Rotate for bar rather than column chart - if (($groupID == 0) && ($rotation == 'bar')) { - $this->graph->Set90AndMargin(); - } - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - - $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); - // Rotate for bar rather than column chart - if ($rotation == 'bar') { - $datasetLabels = array_reverse($datasetLabels); - $this->graph->yaxis->SetPos('max'); - $this->graph->yaxis->SetLabelAlign('center', 'top'); - $this->graph->yaxis->SetLabelSide(SIDE_RIGHT); - } - $this->graph->xaxis->SetTickLabels($datasetLabels); - } - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = []; - if ($grouping == 'percentStacked') { - $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); - } else { - $sumValues = []; - } - - // Loop through each data series in turn - for ($j = 0; $j < $seriesCount; ++$j) { - $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); - if ($grouping == 'percentStacked') { - $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); - } - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach ($dataValues as $k => $dataValue) { - while ($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - // Reverse the $dataValues order for bar rather than column chart - if ($rotation == 'bar') { - $dataValues = array_reverse($dataValues); - } - $seriesPlot = new BarPlot($dataValues); - $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); - if ($dimensions == '3d') { - $seriesPlot->SetShadow(); - } - if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { - $dataLabel = ''; - } else { - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); - } - $seriesPlot->SetLegend($dataLabel); - - $seriesPlots[] = $seriesPlot; - } - // Reverse the plot order for bar rather than column chart - if (($rotation == 'bar') && ($grouping != 'percentStacked')) { - $seriesPlots = array_reverse($seriesPlots); - } - - if ($grouping == 'clustered') { - $groupPlot = new GroupBarPlot($seriesPlots); - } elseif ($grouping == 'standard') { - $groupPlot = new GroupBarPlot($seriesPlots); - } else { - $groupPlot = new AccBarPlot($seriesPlots); - if ($dimensions == '3d') { - $groupPlot->SetShadow(); - } - } - - $this->graph->Add($groupPlot); - } - - private function renderPlotScatter($groupID, $bubble): void - { - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = []; - - // Loop through each data series in turn - for ($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - - foreach ($dataValuesY as $k => $dataValueY) { - $dataValuesY[$k] = $k; - } - - $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); - if ($scatterStyle == 'lineMarker') { - $seriesPlot->SetLinkPoints(); - $seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]); - } elseif ($scatterStyle == 'smoothMarker') { - $spline = new Spline($dataValuesY, $dataValuesX); - [$splineDataY, $splineDataX] = $spline->Get(count($dataValuesX) * self::$width / 20); - $lplot = new LinePlot($splineDataX, $splineDataY); - $lplot->SetColor(self::$colourSet[self::$plotColour]); - - $this->graph->Add($lplot); - } - - if ($bubble) { - $this->formatPointMarker($seriesPlot, 'dot'); - $seriesPlot->mark->SetColor('black'); - $seriesPlot->mark->SetSize($bubbleSize); - } else { - $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - $this->formatPointMarker($seriesPlot, $marker); - } - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetLegend($dataLabel); - - $this->graph->Add($seriesPlot); - } - } - - private function renderPlotRadar($groupID): void - { - $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = []; - - // Loop through each data series in turn - for ($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - - $dataValues = []; - foreach ($dataValuesY as $k => $dataValueY) { - $dataValues[$k] = implode(' ', array_reverse($dataValueY)); - } - $tmp = array_shift($dataValues); - $dataValues[] = $tmp; - $tmp = array_shift($dataValuesX); - $dataValuesX[] = $tmp; - - $this->graph->SetTitles(array_reverse($dataValues)); - - $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); - - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); - if ($radarStyle == 'filled') { - $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour]); - } - $this->formatPointMarker($seriesPlot, $marker); - $seriesPlot->SetLegend($dataLabel); - - $this->graph->Add($seriesPlot); - } - } - - private function renderPlotContour($groupID): void - { - $contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = []; - - $dataValues = []; - // Loop through each data series in turn - for ($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - - $dataValues[$i] = $dataValuesX; - } - $seriesPlot = new ContourPlot($dataValues); - - $this->graph->Add($seriesPlot); - } - - private function renderPlotStock($groupID): void - { - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); - - $dataValues = []; - // Loop through each data series in turn and build the plot arrays - foreach ($plotOrder as $i => $v) { - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); - foreach ($dataValuesX as $j => $dataValueX) { - $dataValues[$plotOrder[$i]][$j] = $dataValueX; - } - } - if (empty($dataValues)) { - return; - } - - $dataValuesPlot = []; - // Flatten the plot arrays to a single dimensional array to work with jpgraph - $jMax = count($dataValues[0]); - for ($j = 0; $j < $jMax; ++$j) { - for ($i = 0; $i < $seriesCount; ++$i) { - $dataValuesPlot[] = $dataValues[$i][$j]; - } - } - - // Set the x-axis labels - $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->graph->xaxis->SetTickLabels($datasetLabels); - } - - $seriesPlot = new StockPlot($dataValuesPlot); - $seriesPlot->SetWidth(20); - - $this->graph->Add($seriesPlot); - } - - private function renderAreaChart($groupCount, $dimensions = '2d'): void - { - $this->renderCartesianPlotArea(); - - for ($i = 0; $i < $groupCount; ++$i) { - $this->renderPlotLine($i, true, false, $dimensions); - } - } - - private function renderLineChart($groupCount, $dimensions = '2d'): void - { - $this->renderCartesianPlotArea(); - - for ($i = 0; $i < $groupCount; ++$i) { - $this->renderPlotLine($i, false, false, $dimensions); - } - } - - private function renderBarChart($groupCount, $dimensions = '2d'): void - { - $this->renderCartesianPlotArea(); - - for ($i = 0; $i < $groupCount; ++$i) { - $this->renderPlotBar($i, $dimensions); - } - } - - private function renderScatterChart($groupCount): void - { - $this->renderCartesianPlotArea('linlin'); - - for ($i = 0; $i < $groupCount; ++$i) { - $this->renderPlotScatter($i, false); - } - } - - private function renderBubbleChart($groupCount): void - { - $this->renderCartesianPlotArea('linlin'); - - for ($i = 0; $i < $groupCount; ++$i) { - $this->renderPlotScatter($i, true); - } - } - - private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false): void - { - $this->renderPiePlotArea(); - - $iLimit = ($multiplePlots) ? $groupCount : 1; - for ($groupID = 0; $groupID < $iLimit; ++$groupID) { - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - $datasetLabels = []; - if ($groupID == 0) { - $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); - } - } - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = []; - // For pie charts, we only display the first series: doughnut charts generally display all series - $jLimit = ($multiplePlots) ? $seriesCount : 1; - // Loop through each data series in turn - for ($j = 0; $j < $jLimit; ++$j) { - $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach ($dataValues as $k => $dataValue) { - while ($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - if ($dimensions == '3d') { - $seriesPlot = new PiePlot3D($dataValues); - } else { - if ($doughnut) { - $seriesPlot = new PiePlotC($dataValues); - } else { - $seriesPlot = new PiePlot($dataValues); - } - } - - if ($multiplePlots) { - $seriesPlot->SetSize(($jLimit - $j) / ($jLimit * 4)); - } - - if ($doughnut) { - $seriesPlot->SetMidColor('white'); - } - - $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); - if (count($datasetLabels) > 0) { - $seriesPlot->SetLabels(array_fill(0, count($datasetLabels), '')); - } - if ($dimensions != '3d') { - $seriesPlot->SetGuideLines(false); - } - if ($j == 0) { - if ($exploded) { - $seriesPlot->ExplodeAll(); - } - $seriesPlot->SetLegends($datasetLabels); - } - - $this->graph->Add($seriesPlot); - } - } - } - - private function renderRadarChart($groupCount): void - { - $this->renderRadarPlotArea(); - - for ($groupID = 0; $groupID < $groupCount; ++$groupID) { - $this->renderPlotRadar($groupID); - } - } - - private function renderStockChart($groupCount): void - { - $this->renderCartesianPlotArea('intint'); - - for ($groupID = 0; $groupID < $groupCount; ++$groupID) { - $this->renderPlotStock($groupID); - } - } - - private function renderContourChart($groupCount, $dimensions): void - { - $this->renderCartesianPlotArea('intint'); - - for ($i = 0; $i < $groupCount; ++$i) { - $this->renderPlotContour($i); - } - } - - private function renderCombinationChart($groupCount, $dimensions, $outputDestination) - { - $this->renderCartesianPlotArea(); - - for ($i = 0; $i < $groupCount; ++$i) { - $dimensions = null; - $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); - switch ($chartType) { - case 'area3DChart': - $dimensions = '3d'; - // no break - case 'areaChart': - $this->renderPlotLine($i, true, true, $dimensions); - - break; - case 'bar3DChart': - $dimensions = '3d'; - // no break - case 'barChart': - $this->renderPlotBar($i, $dimensions); - - break; - case 'line3DChart': - $dimensions = '3d'; - // no break - case 'lineChart': - $this->renderPlotLine($i, false, true, $dimensions); - - break; - case 'scatterChart': - $this->renderPlotScatter($i, false); - - break; - case 'bubbleChart': - $this->renderPlotScatter($i, true); - - break; - default: - $this->graph = null; - - return false; - } - } - - $this->renderLegend(); - - $this->graph->Stroke($outputDestination); - - return true; - } - - public function render($outputDestination) - { - self::$plotColour = 0; - - $groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); - - $dimensions = null; - if ($groupCount == 1) { - $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); - } else { - $chartTypes = []; - for ($i = 0; $i < $groupCount; ++$i) { - $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); - } - $chartTypes = array_unique($chartTypes); - if (count($chartTypes) == 1) { - $chartType = array_pop($chartTypes); - } elseif (count($chartTypes) == 0) { - echo 'Chart is not yet implemented
'; - - return false; - } else { - return $this->renderCombinationChart($groupCount, $dimensions, $outputDestination); - } - } - - switch ($chartType) { - case 'area3DChart': - $dimensions = '3d'; - // no break - case 'areaChart': - $this->renderAreaChart($groupCount, $dimensions); - - break; - case 'bar3DChart': - $dimensions = '3d'; - // no break - case 'barChart': - $this->renderBarChart($groupCount, $dimensions); - - break; - case 'line3DChart': - $dimensions = '3d'; - // no break - case 'lineChart': - $this->renderLineChart($groupCount, $dimensions); - - break; - case 'pie3DChart': - $dimensions = '3d'; - // no break - case 'pieChart': - $this->renderPieChart($groupCount, $dimensions, false, false); - - break; - case 'doughnut3DChart': - $dimensions = '3d'; - // no break - case 'doughnutChart': - $this->renderPieChart($groupCount, $dimensions, true, true); - - break; - case 'scatterChart': - $this->renderScatterChart($groupCount); - - break; - case 'bubbleChart': - $this->renderBubbleChart($groupCount); - - break; - case 'radarChart': - $this->renderRadarChart($groupCount); - - break; - case 'surface3DChart': - $dimensions = '3d'; - // no break - case 'surfaceChart': - $this->renderContourChart($groupCount, $dimensions); - - break; - case 'stockChart': - $this->renderStockChart($groupCount); - - break; - default: - echo $chartType . ' is not yet implemented
'; - - return false; - } - $this->renderLegend(); - - $this->graph->Stroke($outputDestination); - - return true; - } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php new file mode 100644 index 000000000..cb9b544b8 --- /dev/null +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php @@ -0,0 +1,852 @@ +graph = null; + $this->chart = $chart; + + self::$markSet = [ + 'diamond' => MARK_DIAMOND, + 'square' => MARK_SQUARE, + 'triangle' => MARK_UTRIANGLE, + 'x' => MARK_X, + 'star' => MARK_STAR, + 'dot' => MARK_FILLEDCIRCLE, + 'dash' => MARK_DTRIANGLE, + 'circle' => MARK_CIRCLE, + 'plus' => MARK_CROSS, + ]; + } + + /** + * This method should be overriden in descendants to do real JpGraph library initialization. + */ + abstract protected static function init(): void; + + private function formatPointMarker($seriesPlot, $markerID) + { + $plotMarkKeys = array_keys(self::$markSet); + if ($markerID === null) { + // Use default plot marker (next marker in the series) + self::$plotMark %= count(self::$markSet); + $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); + } elseif ($markerID !== 'none') { + // Use specified plot marker (if it exists) + if (isset(self::$markSet[$markerID])) { + $seriesPlot->mark->SetType(self::$markSet[$markerID]); + } else { + // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) + self::$plotMark %= count(self::$markSet); + $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); + } + } else { + // Hide plot marker + $seriesPlot->mark->Hide(); + } + $seriesPlot->mark->SetColor(self::$colourSet[self::$plotColour]); + $seriesPlot->mark->SetFillColor(self::$colourSet[self::$plotColour]); + $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); + + return $seriesPlot; + } + + private function formatDataSetLabels($groupID, $datasetLabels, $rotation = '') + { + $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode() ?? ''; + // Retrieve any label formatting code + $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); + + $testCurrentIndex = 0; + foreach ($datasetLabels as $i => $datasetLabel) { + if (is_array($datasetLabel)) { + if ($rotation == 'bar') { + $datasetLabels[$i] = implode(' ', $datasetLabel); + } else { + $datasetLabel = array_reverse($datasetLabel); + $datasetLabels[$i] = implode("\n", $datasetLabel); + } + } else { + // Format labels according to any formatting code + if ($datasetLabelFormatCode !== null) { + $datasetLabels[$i] = NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); + } + } + ++$testCurrentIndex; + } + + return $datasetLabels; + } + + private function percentageSumCalculation($groupID, $seriesCount) + { + $sumValues = []; + // Adjust our values to a percentage value across all series in the group + for ($i = 0; $i < $seriesCount; ++$i) { + if ($i == 0) { + $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + } else { + $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach ($nextValues as $k => $value) { + if (isset($sumValues[$k])) { + $sumValues[$k] += $value; + } else { + $sumValues[$k] = $value; + } + } + } + } + + return $sumValues; + } + + private function percentageAdjustValues($dataValues, $sumValues) + { + foreach ($dataValues as $k => $dataValue) { + $dataValues[$k] = $dataValue / $sumValues[$k] * 100; + } + + return $dataValues; + } + + private function getCaption($captionElement) + { + // Read any caption + $caption = ($captionElement !== null) ? $captionElement->getCaption() : null; + // Test if we have a title caption to display + if ($caption !== null) { + // If we do, it could be a plain string or an array + if (is_array($caption)) { + // Implode an array to a plain string + $caption = implode('', $caption); + } + } + + return $caption; + } + + private function renderTitle(): void + { + $title = $this->getCaption($this->chart->getTitle()); + if ($title !== null) { + $this->graph->title->Set($title); + } + } + + private function renderLegend(): void + { + $legend = $this->chart->getLegend(); + if ($legend !== null) { + $legendPosition = $legend->getPosition(); + switch ($legendPosition) { + case 'r': + $this->graph->legend->SetPos(0.01, 0.5, 'right', 'center'); // right + $this->graph->legend->SetColumns(1); + + break; + case 'l': + $this->graph->legend->SetPos(0.01, 0.5, 'left', 'center'); // left + $this->graph->legend->SetColumns(1); + + break; + case 't': + $this->graph->legend->SetPos(0.5, 0.01, 'center', 'top'); // top + + break; + case 'b': + $this->graph->legend->SetPos(0.5, 0.99, 'center', 'bottom'); // bottom + + break; + default: + $this->graph->legend->SetPos(0.01, 0.01, 'right', 'top'); // top-right + $this->graph->legend->SetColumns(1); + + break; + } + } else { + $this->graph->legend->Hide(); + } + } + + private function renderCartesianPlotArea($type = 'textlin'): void + { + $this->graph = new Graph(self::$width, self::$height); + $this->graph->SetScale($type); + + $this->renderTitle(); + + // Rotate for bar rather than column chart + $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); + $reverse = $rotation == 'bar'; + + $xAxisLabel = $this->chart->getXAxisLabel(); + if ($xAxisLabel !== null) { + $title = $this->getCaption($xAxisLabel); + if ($title !== null) { + $this->graph->xaxis->SetTitle($title, 'center'); + $this->graph->xaxis->title->SetMargin(35); + if ($reverse) { + $this->graph->xaxis->title->SetAngle(90); + $this->graph->xaxis->title->SetMargin(90); + } + } + } + + $yAxisLabel = $this->chart->getYAxisLabel(); + if ($yAxisLabel !== null) { + $title = $this->getCaption($yAxisLabel); + if ($title !== null) { + $this->graph->yaxis->SetTitle($title, 'center'); + if ($reverse) { + $this->graph->yaxis->title->SetAngle(0); + $this->graph->yaxis->title->SetMargin(-55); + } + } + } + } + + private function renderPiePlotArea(): void + { + $this->graph = new PieGraph(self::$width, self::$height); + + $this->renderTitle(); + } + + private function renderRadarPlotArea(): void + { + $this->graph = new RadarGraph(self::$width, self::$height); + $this->graph->SetScale('lin'); + + $this->renderTitle(); + } + + private function renderPlotLine($groupID, $filled = false, $combination = false): void + { + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[0]; + $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getPointCount(); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels); + $this->graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = []; + if ($grouping == 'percentStacked') { + $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); + } else { + $sumValues = []; + } + + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[$i]; + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getDataValues(); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getPointMarker(); + + if ($grouping == 'percentStacked') { + $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + $seriesPlot = new LinePlot($dataValues); + if ($combination) { + $seriesPlot->SetBarCenter(); + } + + if ($filled) { + $seriesPlot->SetFilled(true); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); + } else { + // Set the appropriate plot marker + $this->formatPointMarker($seriesPlot, $marker); + } + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + + if ($grouping == 'standard') { + $groupPlot = $seriesPlots; + } else { + $groupPlot = new AccLinePlot($seriesPlots); + } + $this->graph->Add($groupPlot); + } + + private function renderPlotBar($groupID, $dimensions = '2d'): void + { + $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); + // Rotate for bar rather than column chart + if (($groupID == 0) && ($rotation == 'bar')) { + $this->graph->Set90AndMargin(); + } + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[0]; + $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getPointCount(); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $rotation); + // Rotate for bar rather than column chart + if ($rotation == 'bar') { + $datasetLabels = array_reverse($datasetLabels); + $this->graph->yaxis->SetPos('max'); + $this->graph->yaxis->SetLabelAlign('center', 'top'); + $this->graph->yaxis->SetLabelSide(SIDE_RIGHT); + } + $this->graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = []; + if ($grouping == 'percentStacked') { + $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); + } else { + $sumValues = []; + } + + // Loop through each data series in turn + for ($j = 0; $j < $seriesCount; ++$j) { + $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[$j]; + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getDataValues(); + if ($grouping == 'percentStacked') { + $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + // Reverse the $dataValues order for bar rather than column chart + if ($rotation == 'bar') { + $dataValues = array_reverse($dataValues); + } + $seriesPlot = new BarPlot($dataValues); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); + if ($dimensions == '3d') { + $seriesPlot->SetShadow(); + } + if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { + $dataLabel = ''; + } else { + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); + } + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + // Reverse the plot order for bar rather than column chart + if (($rotation == 'bar') && ($grouping != 'percentStacked')) { + $seriesPlots = array_reverse($seriesPlots); + } + + if ($grouping == 'clustered') { + $groupPlot = new GroupBarPlot($seriesPlots); + } elseif ($grouping == 'standard') { + $groupPlot = new GroupBarPlot($seriesPlots); + } else { + $groupPlot = new AccBarPlot($seriesPlots); + if ($dimensions == '3d') { + $groupPlot->SetShadow(); + } + } + + $this->graph->Add($groupPlot); + } + + private function renderPlotScatter($groupID, $bubble): void + { + $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + foreach ($dataValuesY as $k => $dataValueY) { + $dataValuesY[$k] = $k; + } + + $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); + if ($scatterStyle == 'lineMarker') { + $seriesPlot->SetLinkPoints(); + $seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]); + } elseif ($scatterStyle == 'smoothMarker') { + $spline = new Spline($dataValuesY, $dataValuesX); + [$splineDataY, $splineDataX] = $spline->Get(count($dataValuesX) * self::$width / 20); + $lplot = new LinePlot($splineDataX, $splineDataY); + $lplot->SetColor(self::$colourSet[self::$plotColour]); + + $this->graph->Add($lplot); + } + + if ($bubble) { + $this->formatPointMarker($seriesPlot, 'dot'); + $seriesPlot->mark->SetColor('black'); + $seriesPlot->mark->SetSize($bubbleSize); + } else { + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $this->formatPointMarker($seriesPlot, $marker); + } + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $this->graph->Add($seriesPlot); + } + } + + private function renderPlotRadar($groupID): void + { + $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + $dataValues = []; + foreach ($dataValuesY as $k => $dataValueY) { + $dataValues[$k] = implode(' ', array_reverse($dataValueY)); + } + $tmp = array_shift($dataValues); + $dataValues[] = $tmp; + $tmp = array_shift($dataValuesX); + $dataValuesX[] = $tmp; + + $this->graph->SetTitles(array_reverse($dataValues)); + + $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); + + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); + if ($radarStyle == 'filled') { + $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour]); + } + $this->formatPointMarker($seriesPlot, $marker); + $seriesPlot->SetLegend($dataLabel); + + $this->graph->Add($seriesPlot); + } + } + + private function renderPlotContour($groupID): void + { + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + + $dataValues = []; + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + $dataValues[$i] = $dataValuesX; + } + $seriesPlot = new ContourPlot($dataValues); + + $this->graph->Add($seriesPlot); + } + + private function renderPlotStock($groupID): void + { + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + + $dataValues = []; + // Loop through each data series in turn and build the plot arrays + foreach ($plotOrder as $i => $v) { + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v); + if ($dataValuesX === false) { + continue; + } + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); + foreach ($dataValuesX as $j => $dataValueX) { + $dataValues[$plotOrder[$i]][$j] = $dataValueX; + } + } + if (empty($dataValues)) { + return; + } + + $dataValuesPlot = []; + // Flatten the plot arrays to a single dimensional array to work with jpgraph + $jMax = count($dataValues[0]); + for ($j = 0; $j < $jMax; ++$j) { + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesPlot[] = $dataValues[$i][$j] ?? null; + } + } + + // Set the x-axis labels + $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels); + $this->graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesPlot = new StockPlot($dataValuesPlot); + $seriesPlot->SetWidth(20); + + $this->graph->Add($seriesPlot); + } + + private function renderAreaChart($groupCount): void + { + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotLine($i, true, false); + } + } + + private function renderLineChart($groupCount): void + { + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotLine($i, false, false); + } + } + + private function renderBarChart($groupCount, $dimensions = '2d'): void + { + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotBar($i, $dimensions); + } + } + + private function renderScatterChart($groupCount): void + { + $this->renderCartesianPlotArea('linlin'); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotScatter($i, false); + } + } + + private function renderBubbleChart($groupCount): void + { + $this->renderCartesianPlotArea('linlin'); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotScatter($i, true); + } + } + + private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false): void + { + $this->renderPiePlotArea(); + + $iLimit = ($multiplePlots) ? $groupCount : 1; + for ($groupID = 0; $groupID < $iLimit; ++$groupID) { + $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + $datasetLabels = []; + if ($groupID == 0) { + $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels); + } + } + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + // For pie charts, we only display the first series: doughnut charts generally display all series + $jLimit = ($multiplePlots) ? $seriesCount : 1; + // Loop through each data series in turn + for ($j = 0; $j < $jLimit; ++$j) { + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + if ($dimensions == '3d') { + $seriesPlot = new PiePlot3D($dataValues); + } else { + if ($doughnut) { + $seriesPlot = new PiePlotC($dataValues); + } else { + $seriesPlot = new PiePlot($dataValues); + } + } + + if ($multiplePlots) { + $seriesPlot->SetSize(($jLimit - $j) / ($jLimit * 4)); + } + + if ($doughnut && method_exists($seriesPlot, 'SetMidColor')) { + $seriesPlot->SetMidColor('white'); + } + + $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); + if (count($datasetLabels) > 0) { + $seriesPlot->SetLabels(array_fill(0, count($datasetLabels), '')); + } + if ($dimensions != '3d') { + $seriesPlot->SetGuideLines(false); + } + if ($j == 0) { + if ($exploded) { + $seriesPlot->ExplodeAll(); + } + $seriesPlot->SetLegends($datasetLabels); + } + + $this->graph->Add($seriesPlot); + } + } + } + + private function renderRadarChart($groupCount): void + { + $this->renderRadarPlotArea(); + + for ($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->renderPlotRadar($groupID); + } + } + + private function renderStockChart($groupCount): void + { + $this->renderCartesianPlotArea('intint'); + + for ($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->renderPlotStock($groupID); + } + } + + private function renderContourChart($groupCount): void + { + $this->renderCartesianPlotArea('intint'); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotContour($i); + } + } + + private function renderCombinationChart($groupCount, $outputDestination) + { + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $dimensions = null; + $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + switch ($chartType) { + case 'area3DChart': + case 'areaChart': + $this->renderPlotLine($i, true, true); + + break; + case 'bar3DChart': + $dimensions = '3d'; + // no break + case 'barChart': + $this->renderPlotBar($i, $dimensions); + + break; + case 'line3DChart': + case 'lineChart': + $this->renderPlotLine($i, false, true); + + break; + case 'scatterChart': + $this->renderPlotScatter($i, false); + + break; + case 'bubbleChart': + $this->renderPlotScatter($i, true); + + break; + default: + $this->graph = null; + + return false; + } + } + + $this->renderLegend(); + + $this->graph->Stroke($outputDestination); + + return true; + } + + public function render($outputDestination) + { + self::$plotColour = 0; + + $groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); + + $dimensions = null; + if ($groupCount == 1) { + $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); + } else { + $chartTypes = []; + for ($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + } + $chartTypes = array_unique($chartTypes); + if (count($chartTypes) == 1) { + $chartType = array_pop($chartTypes); + } elseif (count($chartTypes) == 0) { + echo 'Chart is not yet implemented
'; + + return false; + } else { + return $this->renderCombinationChart($groupCount, $outputDestination); + } + } + + switch ($chartType) { + case 'area3DChart': + $dimensions = '3d'; + // no break + case 'areaChart': + $this->renderAreaChart($groupCount); + + break; + case 'bar3DChart': + $dimensions = '3d'; + // no break + case 'barChart': + $this->renderBarChart($groupCount, $dimensions); + + break; + case 'line3DChart': + $dimensions = '3d'; + // no break + case 'lineChart': + $this->renderLineChart($groupCount); + + break; + case 'pie3DChart': + $dimensions = '3d'; + // no break + case 'pieChart': + $this->renderPieChart($groupCount, $dimensions, false, false); + + break; + case 'doughnut3DChart': + $dimensions = '3d'; + // no break + case 'doughnutChart': + $this->renderPieChart($groupCount, $dimensions, true, true); + + break; + case 'scatterChart': + $this->renderScatterChart($groupCount); + + break; + case 'bubbleChart': + $this->renderBubbleChart($groupCount); + + break; + case 'radarChart': + $this->renderRadarChart($groupCount); + + break; + case 'surface3DChart': + case 'surfaceChart': + $this->renderContourChart($groupCount); + + break; + case 'stockChart': + $this->renderStockChart($groupCount); + + break; + default: + echo $chartType . ' is not yet implemented
'; + + return false; + } + $this->renderLegend(); + + $this->graph->Stroke($outputDestination); + + return true; + } +} diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/MtJpGraphRenderer.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/MtJpGraphRenderer.php new file mode 100644 index 000000000..e1f0f90ad --- /dev/null +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/Renderer/MtJpGraphRenderer.php @@ -0,0 +1,36 @@ +setTrendLineProperties( + $trendLineType, + $order, + $period, + $dispRSqr, + $dispEq, + $backward, + $forward, + $intercept, + $name + ); + } + + public function getTrendLineType(): string + { + return $this->trendLineType; + } + + public function setTrendLineType(string $trendLineType): self + { + $this->trendLineType = $trendLineType; + + return $this; + } + + public function getOrder(): int + { + return $this->order; + } + + public function setOrder(int $order): self + { + $this->order = $order; + + return $this; + } + + public function getPeriod(): int + { + return $this->period; + } + + public function setPeriod(int $period): self + { + $this->period = $period; + + return $this; + } + + public function getDispRSqr(): bool + { + return $this->dispRSqr; + } + + public function setDispRSqr(bool $dispRSqr): self + { + $this->dispRSqr = $dispRSqr; + + return $this; + } + + public function getDispEq(): bool + { + return $this->dispEq; + } + + public function setDispEq(bool $dispEq): self + { + $this->dispEq = $dispEq; + + return $this; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function getBackward(): float + { + return $this->backward; + } + + public function setBackward(float $backward): self + { + $this->backward = $backward; + + return $this; + } + + public function getForward(): float + { + return $this->forward; + } + + public function setForward(float $forward): self + { + $this->forward = $forward; + + return $this; + } + + public function getIntercept(): float + { + return $this->intercept; + } + + public function setIntercept(float $intercept): self + { + $this->intercept = $intercept; + + return $this; + } + + public function setTrendLineProperties( + ?string $trendLineType = null, + ?int $order = 0, + ?int $period = 0, + ?bool $dispRSqr = false, + ?bool $dispEq = false, + ?float $backward = null, + ?float $forward = null, + ?float $intercept = null, + ?string $name = null + ): self { + if (!empty($trendLineType)) { + $this->setTrendLineType($trendLineType); + } + if ($order !== null) { + $this->setOrder($order); + } + if ($period !== null) { + $this->setPeriod($period); + } + if ($dispRSqr !== null) { + $this->setDispRSqr($dispRSqr); + } + if ($dispEq !== null) { + $this->setDispEq($dispEq); + } + if ($backward !== null) { + $this->setBackward($backward); + } + if ($forward !== null) { + $this->setForward($forward); + } + if ($intercept !== null) { + $this->setIntercept($intercept); + } + if ($name !== null) { + $this->setName($name); + } + + return $this; + } +} diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php index 20fccf48a..82c9ae1ae 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php @@ -91,10 +91,8 @@ class Cells * Whether the collection holds a cell for the given coordinate. * * @param string $cellCoordinate Coordinate of the cell to check - * - * @return bool */ - public function has($cellCoordinate) + public function has($cellCoordinate): bool { return ($cellCoordinate === $this->currentCoordinate) || isset($this->index[$cellCoordinate]); } @@ -103,10 +101,8 @@ class Cells * Add or update a cell in the collection. * * @param Cell $cell Cell to update - * - * @return Cell */ - public function update(Cell $cell) + public function update(Cell $cell): Cell { return $this->add($cell->getCoordinate(), $cell); } @@ -165,10 +161,8 @@ class Cells /** * Return the column coordinate of the currently active cell object. - * - * @return string */ - public function getCurrentColumn() + public function getCurrentColumn(): string { sscanf($this->currentCoordinate ?? '', '%[A-Z]%d', $column, $row); @@ -177,10 +171,8 @@ class Cells /** * Return the row coordinate of the currently active cell object. - * - * @return int */ - public function getCurrentRow() + public function getCurrentRow(): int { sscanf($this->currentCoordinate ?? '', '%[A-Z]%d', $column, $row); @@ -276,7 +268,9 @@ class Cells */ private function getUniqueID() { - return Settings::getCache() instanceof Memory + $cacheType = Settings::getCache(); + + return ($cacheType instanceof Memory\SimpleCache1 || $cacheType instanceof Memory\SimpleCache3) ? random_bytes(7) . ':' : uniqid('phpspreadsheet.', true) . '.'; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/CellsFactory.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/CellsFactory.php index 26f18dfc5..b3833bd8b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/CellsFactory.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/CellsFactory.php @@ -12,9 +12,8 @@ abstract class CellsFactory * * @param Worksheet $worksheet Enable cell caching for this worksheet * - * @return Cells * */ - public static function getInstance(Worksheet $worksheet) + public static function getInstance(Worksheet $worksheet): Cells { return new Cells($worksheet, Settings::getCache()); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php similarity index 93% rename from vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory.php rename to vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php index 2690ab7d0..a0eb6ec22 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php @@ -1,6 +1,6 @@ cache = []; + + return true; + } + + /** + * @param string $key + */ + public function delete($key): bool + { + unset($this->cache[$key]); + + return true; + } + + /** + * @param iterable $keys + */ + public function deleteMultiple($keys): bool + { + foreach ($keys as $key) { + $this->delete($key); + } + + return true; + } + + /** + * @param string $key + * @param mixed $default + */ + public function get($key, $default = null): mixed + { + if ($this->has($key)) { + return $this->cache[$key]; + } + + return $default; + } + + /** + * @param iterable $keys + * @param mixed $default + */ + public function getMultiple($keys, $default = null): iterable + { + $results = []; + foreach ($keys as $key) { + $results[$key] = $this->get($key, $default); + } + + return $results; + } + + /** + * @param string $key + */ + public function has($key): bool + { + return array_key_exists($key, $this->cache); + } + + /** + * @param string $key + * @param mixed $value + * @param null|DateInterval|int $ttl + */ + public function set($key, $value, $ttl = null): bool + { + $this->cache[$key] = $value; + + return true; + } + + /** + * @param iterable $values + * @param null|DateInterval|int $ttl + */ + public function setMultiple($values, $ttl = null): bool + { + foreach ($values as $key => $value) { + $this->set($key, $value); + } + + return true; + } +} diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/DefinedName.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/DefinedName.php index 3b874b435..464fa8e34 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/DefinedName.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/DefinedName.php @@ -150,7 +150,7 @@ abstract class DefinedName // New title $newTitle = $this->name; - ReferenceHelper::getInstance()->updateNamedFormulas($this->worksheet->getParent(), $oldTitle, $newTitle); + ReferenceHelper::getInstance()->updateNamedFormulae($this->worksheet->getParent(), $oldTitle, $newTitle); } return $this; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php index 425c9a616..ff07ce5b8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Dimension.php @@ -55,10 +55,20 @@ class Dimension */ protected $unit; + /** + * Phpstan bug has been fixed; this function allows us to + * pass Phpstan whether fixed or not. + * + * @param mixed $value + */ + private static function stanBugFixed($value): array + { + return is_array($value) ? $value : [null, null]; + } + public function __construct(string $dimension) { - // @phpstan-ignore-next-line - [$size, $unit] = sscanf($dimension, '%[1234567890.]%s'); + [$size, $unit] = self::stanBugFixed(sscanf($dimension, '%[1234567890.]%s')); $unit = strtolower(trim($unit ?? '')); $size = (float) $size; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php index 8ce37003c..0ac0c7969 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Sample.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Helper; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Writer\IWriter; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; @@ -84,7 +85,7 @@ class Sample foreach ($regex as $file) { $file = str_replace(str_replace('\\', '/', $baseDir) . '/', '', str_replace('\\', '/', $file[0])); $info = pathinfo($file); - $category = str_replace('_', ' ', $info['dirname']); + $category = str_replace('_', ' ', $info['dirname'] ?? ''); $name = str_replace('_', ' ', (string) preg_replace('/(|\.php)/', '', $info['filename'])); if (!in_array($category, ['.', 'boostrap', 'templates'])) { if (!isset($files[$category])) { @@ -182,6 +183,33 @@ class Sample echo date('H:i:s ') . $message . $eol; } + public function titles(string $category, string $functionName, ?string $description = null): void + { + $this->log(sprintf('%s Functions:', $category)); + $description === null + ? $this->log(sprintf('Function: %s()', rtrim($functionName, '()'))) + : $this->log(sprintf('Function: %s() - %s.', rtrim($functionName, '()'), rtrim($description, '.'))); + } + + public function displayGrid(array $matrix): void + { + $renderer = new TextGrid($matrix, $this->isCli()); + echo $renderer->render(); + } + + public function logCalculationResult( + Worksheet $worksheet, + string $functionName, + string $formulaCell, + ?string $descriptionCell = null + ): void { + if ($descriptionCell !== null) { + $this->log($worksheet->getCell($descriptionCell)->getValue()); + } + $this->log($worksheet->getCell($formulaCell)->getValue()); + $this->log(sprintf('%s() Result is ', $functionName) . $worksheet->getCell($formulaCell)->getCalculatedValue()); + } + /** * Log ending notes. */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php new file mode 100644 index 000000000..acb9ae60e --- /dev/null +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/TextGrid.php @@ -0,0 +1,139 @@ +rows = array_keys($matrix); + $this->columns = array_keys($matrix[$this->rows[0]]); + + $matrix = array_values($matrix); + array_walk( + $matrix, + function (&$row): void { + $row = array_values($row); + } + ); + + $this->matrix = $matrix; + $this->isCli = $isCli; + } + + public function render(): string + { + $this->gridDisplay = $this->isCli ? '' : ''; + + $maxRow = max($this->rows); + $maxRowLength = strlen((string) $maxRow) + 1; + $columnWidths = $this->getColumnWidths($this->matrix); + + $this->renderColumnHeader($maxRowLength, $columnWidths); + $this->renderRows($maxRowLength, $columnWidths); + $this->renderFooter($maxRowLength, $columnWidths); + + $this->gridDisplay .= $this->isCli ? '' : ''; + + return $this->gridDisplay; + } + + private function renderRows(int $maxRowLength, array $columnWidths): void + { + foreach ($this->matrix as $row => $rowData) { + $this->gridDisplay .= '|' . str_pad((string) $this->rows[$row], $maxRowLength, ' ', STR_PAD_LEFT) . ' '; + $this->renderCells($rowData, $columnWidths); + $this->gridDisplay .= '|' . PHP_EOL; + } + } + + private function renderCells(array $rowData, array $columnWidths): void + { + foreach ($rowData as $column => $cell) { + $cell = ($this->isCli) ? (string) $cell : htmlentities((string) $cell); + $this->gridDisplay .= '| '; + $this->gridDisplay .= str_pad($cell, $columnWidths[$column] + 1, ' '); + } + } + + private function renderColumnHeader(int $maxRowLength, array $columnWidths): void + { + $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); + foreach ($this->columns as $column => $reference) { + $this->gridDisplay .= '+-' . str_repeat('-', $columnWidths[$column] + 1); + } + $this->gridDisplay .= '+' . PHP_EOL; + + $this->gridDisplay .= str_repeat(' ', $maxRowLength + 2); + foreach ($this->columns as $column => $reference) { + $this->gridDisplay .= '| ' . str_pad((string) $reference, $columnWidths[$column] + 1, ' '); + } + $this->gridDisplay .= '|' . PHP_EOL; + + $this->renderFooter($maxRowLength, $columnWidths); + } + + private function renderFooter(int $maxRowLength, array $columnWidths): void + { + $this->gridDisplay .= '+' . str_repeat('-', $maxRowLength + 1); + foreach ($this->columns as $column => $reference) { + $this->gridDisplay .= '+-'; + $this->gridDisplay .= str_pad((string) '', $columnWidths[$column] + 1, '-'); + } + $this->gridDisplay .= '+' . PHP_EOL; + } + + private function getColumnWidths(array $matrix): array + { + $columnCount = count($this->matrix, COUNT_RECURSIVE) / count($this->matrix); + $columnWidths = []; + for ($column = 0; $column < $columnCount; ++$column) { + $columnWidths[] = $this->getColumnWidth(array_column($this->matrix, $column)); + } + + return $columnWidths; + } + + private function getColumnWidth(array $columnData): int + { + $columnWidth = 0; + $columnData = array_values($columnData); + + foreach ($columnData as $columnValue) { + if (is_string($columnValue)) { + $columnWidth = max($columnWidth, strlen($columnValue)); + } elseif (is_bool($columnValue)) { + $columnWidth = max($columnWidth, strlen($columnValue ? 'TRUE' : 'FALSE')); + } + + $columnWidth = max($columnWidth, strlen((string) $columnWidth)); + } + + return $columnWidth; + } +} diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php index ca087e615..1dcb0a125 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Gnumeric.php @@ -363,7 +363,7 @@ class Gnumeric extends BaseReader if ($sheet !== null && isset($sheet->MergedRegions)) { foreach ($sheet->MergedRegions->Merge as $mergeCells) { if (strpos((string) $mergeCells, ':') !== false) { - $this->spreadsheet->getActiveSheet()->mergeCells($mergeCells); + $this->spreadsheet->getActiveSheet()->mergeCells($mergeCells, Worksheet::MERGE_CELL_CONTENT_HIDE); } } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php index 3d859e15f..76f128e02 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php @@ -201,7 +201,7 @@ class Html extends BaseReader /** * Loads Spreadsheet from file. */ - protected function loadSpreadsheetFromFile(string $filename): Spreadsheet + public function loadSpreadsheetFromFile(string $filename): Spreadsheet { // Create new Spreadsheet $spreadsheet = new Spreadsheet(); @@ -651,7 +651,13 @@ class Html extends BaseReader // Reload the HTML file into the DOM object try { $convert = $this->securityScanner->scanFile($filename); - $loaded = $dom->loadHTML($convert); + $lowend = "\u{80}"; + $highend = "\u{10ffff}"; + $regexp = "/[$lowend-$highend]/u"; + /** @var callable */ + $callback = [self::class, 'replaceNonAscii']; + $convert = preg_replace_callback($regexp, $callback, $convert); + $loaded = ($convert === null) ? false : $dom->loadHTML($convert); } catch (Throwable $e) { $loaded = false; } @@ -662,6 +668,11 @@ class Html extends BaseReader return $this->loadDocument($dom, $spreadsheet); } + private static function replaceNonAscii(array $matches): string + { + return '&#' . mb_ord($matches[0], 'UTF-8') . ';'; + } + /** * Spreadsheet from content. * @@ -674,7 +685,13 @@ class Html extends BaseReader // Reload the HTML file into the DOM object try { $convert = $this->securityScanner->scan($content); - $loaded = $dom->loadHTML($convert); + $lowend = "\u{80}"; + $highend = "\u{10ffff}"; + $regexp = "/[$lowend-$highend]/u"; + /** @var callable */ + $callback = [self::class, 'replaceNonAscii']; + $convert = preg_replace_callback($regexp, $callback, $convert); + $loaded = ($convert === null) ? false : $dom->loadHTML($convert); } catch (Throwable $e) { $loaded = false; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php index 7e776ab78..e3de47317 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Ods.php @@ -20,6 +20,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Throwable; use XMLReader; use ZipArchive; @@ -759,7 +760,7 @@ class Ods extends BaseReader } $cellRange = $columnID . $rowID . ':' . $columnTo . $rowTo; - $spreadsheet->getActiveSheet()->mergeCells($cellRange); + $spreadsheet->getActiveSheet()->mergeCells($cellRange, Worksheet::MERGE_CELL_CONTENT_HIDE); } } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php index 8155b838f..40008d01d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Security/XmlScanner.php @@ -52,7 +52,7 @@ class XmlScanner public static function threadSafeLibxmlDisableEntityLoaderAvailability() { - if (PHP_MAJOR_VERSION == 7) { + if (PHP_MAJOR_VERSION === 7) { switch (PHP_MINOR_VERSION) { case 2: return PHP_RELEASE_VERSION >= 1; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php index 9f8a3ace9..a8de52282 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xls.php @@ -4585,7 +4585,7 @@ class Xls extends BaseReader (strpos($cellRangeAddress, ':') !== false) && ($this->includeCellRangeFiltered($cellRangeAddress)) ) { - $this->phpSheet->mergeCells($cellRangeAddress); + $this->phpSheet->mergeCells($cellRangeAddress, Worksheet::MERGE_CELL_CONTENT_HIDE); } } } @@ -6999,7 +6999,7 @@ class Xls extends BaseReader } break; - // Unknown cases // don't know how to deal with + // Unknown cases // don't know how to deal with default: throw new Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php index 52df94e4c..e2fae121b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php @@ -31,6 +31,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Font; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Color; +use PhpOffice\PhpSpreadsheet\Style\Font as StyleFont; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing; @@ -293,7 +294,7 @@ class Xlsx extends BaseReader return $worksheetInfo; } - private static function castToBoolean($c) + private static function castToBoolean(SimpleXMLElement $c): bool { $value = isset($c->v) ? (string) $c->v : null; if ($value == '0') { @@ -305,18 +306,25 @@ class Xlsx extends BaseReader return (bool) $c->v; } - private static function castToError($c) + private static function castToError(?SimpleXMLElement $c): ?string { - return isset($c->v) ? (string) $c->v : null; + return isset($c, $c->v) ? (string) $c->v : null; } - private static function castToString($c) + private static function castToString(?SimpleXMLElement $c): ?string { - return isset($c->v) ? (string) $c->v : null; + return isset($c, $c->v) ? (string) $c->v : null; } - private function castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType): void + /** + * @param mixed $value + * @param mixed $calculatedValue + */ + private function castToFormula(?SimpleXMLElement $c, string $r, string &$cellDataType, &$value, &$calculatedValue, array &$sharedFormulas, string $castBaseType): void { + if ($c === null) { + return; + } $attr = $c->f->attributes(); $cellDataType = 'f'; $value = "={$c->f}"; @@ -389,7 +397,7 @@ class Xlsx extends BaseReader $contents = $archive->getFromName(substr($fileName, 1), 0, ZipArchive::FL_NOCASE); } - return $contents; + return ($contents === false) ? '' : $contents; } /** @@ -479,7 +487,7 @@ class Xlsx extends BaseReader $propertyReader->readCustomProperties($this->getFromZipArchive($zip, $relTarget)); break; - //Ribbon + //Ribbon case Namespaces::EXTENSIBILITY: $customUI = $relTarget; if ($customUI) { @@ -530,7 +538,7 @@ class Xlsx extends BaseReader } break; - // a vbaProject ? (: some macros) + // a vbaProject ? (: some macros) case Namespaces::VBA: $macros = $ele['Target']; @@ -906,7 +914,7 @@ class Xlsx extends BaseReader foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { $mergeRef = (string) $mergeCell['ref']; if (strpos($mergeRef, ':') !== false) { - $docSheet->mergeCells((string) $mergeCell['ref']); + $docSheet->mergeCells((string) $mergeCell['ref'], Worksheet::MERGE_CELL_CONTENT_HIDE); } } } @@ -1143,7 +1151,7 @@ class Xlsx extends BaseReader } // Header/footer images - if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->readDataOnly) { + if ($xmlSheet && $xmlSheet->legacyDrawingHF) { if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { $relsWorksheet = $this->loadZipNoNamespace(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels', Namespaces::RELATIONSHIPS); $vmlRelationship = ''; @@ -1550,7 +1558,7 @@ class Xlsx extends BaseReader break; case '_xlnm.Print_Area': - $rangeSets = preg_split("/('?(?:.*?)'?(?:![A-Z0-9]+:[A-Z0-9]+)),?/", $extractedRange, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); + $rangeSets = preg_split("/('?(?:.*?)'?(?:![A-Z0-9]+:[A-Z0-9]+)),?/", $extractedRange, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) ?: []; $newRangeSets = []; foreach ($rangeSets as $rangeSet) { [, $rangeSet] = Worksheet::extractSheetTitle($rangeSet, true); @@ -1605,7 +1613,7 @@ class Xlsx extends BaseReader if (strpos((string) $definedName, '!') !== false) { $range[0] = str_replace("''", "'", $range[0]); $range[0] = str_replace("'", '', $range[0]); - if ($worksheet = $excel->getSheetByName($range[0])) { + if ($worksheet = $excel->getSheetByName($range[0])) { // @phpstan-ignore-line $excel->addDefinedName(DefinedName::createInstance((string) $definedName['name'], $worksheet, $extractedRange, true, $scope)); } else { $excel->addDefinedName(DefinedName::createInstance((string) $definedName['name'], $scope, $extractedRange, true, $scope)); @@ -1626,7 +1634,7 @@ class Xlsx extends BaseReader // Need to split on a comma or a space if not in quotes, and extract the first part. $definedNameValueParts = preg_split("/[ ,](?=([^']*'[^']*')*[^']*$)/miuU", $definedRange); // Extract sheet name - [$extractedSheetName] = Worksheet::extractSheetTitle((string) $definedNameValueParts[0], true); + [$extractedSheetName] = Worksheet::extractSheetTitle((string) $definedNameValueParts[0], true); // @phpstan-ignore-line $extractedSheetName = trim($extractedSheetName, "'"); // Locate sheet @@ -1673,7 +1681,7 @@ class Xlsx extends BaseReader if (isset($charts[$chartEntryRef])) { $chartPositionRef = $charts[$chartEntryRef]['sheet'] . '!' . $charts[$chartEntryRef]['id']; if (isset($chartDetails[$chartPositionRef])) { - $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); + $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); // @phpstan-ignore-line $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); // For oneCellAnchor or absoluteAnchor positioned charts, // toCoordinate is not in the data. Does it need to be calculated? @@ -1695,7 +1703,7 @@ class Xlsx extends BaseReader break; - // unparsed + // unparsed case 'application/vnd.ms-excel.controlproperties+xml': $unparsedLoadedData['override_content_types'][(string) $contentType['PartName']] = (string) $contentType['ContentType']; @@ -1722,28 +1730,28 @@ class Xlsx extends BaseReader $value->createText(StringHelper::controlCharacterOOXML2PHP((string) $is->t)); } else { if (is_object($is->r)) { - /** @var SimpleXMLElement $run */ foreach ($is->r as $run) { if (!isset($run->rPr)) { $value->createText(StringHelper::controlCharacterOOXML2PHP((string) $run->t)); } else { $objText = $value->createTextRun(StringHelper::controlCharacterOOXML2PHP((string) $run->t)); + $objFont = $objText->getFont() ?? new StyleFont(); if (isset($run->rPr->rFont)) { $attr = $run->rPr->rFont->attributes(); if (isset($attr['val'])) { - $objText->getFont()->setName((string) $attr['val']); + $objFont->setName((string) $attr['val']); } } if (isset($run->rPr->sz)) { $attr = $run->rPr->sz->attributes(); if (isset($attr['val'])) { - $objText->getFont()->setSize((float) $attr['val']); + $objFont->setSize((float) $attr['val']); } } if (isset($run->rPr->color)) { - $objText->getFont()->setColor(new Color($this->styleReader->readColor($run->rPr->color))); + $objFont->setColor(new Color($this->styleReader->readColor($run->rPr->color))); } if (isset($run->rPr->b)) { $attr = $run->rPr->b->attributes(); @@ -1751,7 +1759,7 @@ class Xlsx extends BaseReader (isset($attr['val']) && self::boolean((string) $attr['val'])) || (!isset($attr['val'])) ) { - $objText->getFont()->setBold(true); + $objFont->setBold(true); } } if (isset($run->rPr->i)) { @@ -1760,7 +1768,7 @@ class Xlsx extends BaseReader (isset($attr['val']) && self::boolean((string) $attr['val'])) || (!isset($attr['val'])) ) { - $objText->getFont()->setItalic(true); + $objFont->setItalic(true); } } if (isset($run->rPr->vertAlign)) { @@ -1768,19 +1776,19 @@ class Xlsx extends BaseReader if (isset($attr['val'])) { $vertAlign = strtolower((string) $attr['val']); if ($vertAlign == 'superscript') { - $objText->getFont()->setSuperscript(true); + $objFont->setSuperscript(true); } if ($vertAlign == 'subscript') { - $objText->getFont()->setSubscript(true); + $objFont->setSubscript(true); } } } if (isset($run->rPr->u)) { $attr = $run->rPr->u->attributes(); if (!isset($attr['val'])) { - $objText->getFont()->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE); + $objFont->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE); } else { - $objText->getFont()->setUnderline((string) $attr['val']); + $objFont->setUnderline((string) $attr['val']); } } if (isset($run->rPr->strike)) { @@ -1789,7 +1797,7 @@ class Xlsx extends BaseReader (isset($attr['val']) && self::boolean((string) $attr['val'])) || (!isset($attr['val'])) ) { - $objText->getFont()->setStrikethrough(true); + $objFont->setStrikethrough(true); } } } @@ -1842,17 +1850,30 @@ class Xlsx extends BaseReader } } + /** + * @param null|array|bool|SimpleXMLElement $array + * @param int|string $key + * + * @return mixed + */ private static function getArrayItem($array, $key = 0) { - return $array[$key] ?? null; + return ($array === null || is_bool($array)) ? null : ($array[$key] ?? null); } + /** + * @param null|SimpleXMLElement|string $base + * @param null|SimpleXMLElement|string $add + */ private static function dirAdd($base, $add): string { + $base = (string) $base; + $add = (string) $add; + return (string) preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); } - private static function toCSSArray($style): array + private static function toCSSArray(string $style): array { $style = self::stripWhiteSpaceFromStyleString($style); @@ -1866,15 +1887,15 @@ class Xlsx extends BaseReader } if (strpos($item[1], 'pt') !== false) { $item[1] = str_replace('pt', '', $item[1]); - $item[1] = Font::fontSizeToPixels($item[1]); + $item[1] = (string) Font::fontSizeToPixels((int) $item[1]); } if (strpos($item[1], 'in') !== false) { $item[1] = str_replace('in', '', $item[1]); - $item[1] = Font::inchSizeToPixels($item[1]); + $item[1] = (string) Font::inchSizeToPixels((int) $item[1]); } if (strpos($item[1], 'cm') !== false) { $item[1] = str_replace('cm', '', $item[1]); - $item[1] = Font::centimeterSizeToPixels($item[1]); + $item[1] = (string) Font::centimeterSizeToPixels((int) $item[1]); } $style[$item[0]] = $item[1]; @@ -1883,11 +1904,14 @@ class Xlsx extends BaseReader return $style; } - public static function stripWhiteSpaceFromStyleString($string): string + public static function stripWhiteSpaceFromStyleString(string $string): string { return trim(str_replace(["\r", "\n", ' '], '', $string), ';'); } + /** + * @param mixed $value + */ private static function boolean($value): bool { if (is_object($value)) { @@ -1956,7 +1980,7 @@ class Xlsx extends BaseReader return $returnValue; } - private function readFormControlProperties(Spreadsheet $excel, $dir, $fileWorksheet, $docSheet, array &$unparsedLoadedData): void + private function readFormControlProperties(Spreadsheet $excel, string $dir, string $fileWorksheet, Worksheet $docSheet, array &$unparsedLoadedData): void { $zip = $this->zip; if (!$zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { @@ -1983,7 +2007,7 @@ class Xlsx extends BaseReader unset($unparsedCtrlProps); } - private function readPrinterSettings(Spreadsheet $excel, $dir, $fileWorksheet, $docSheet, array &$unparsedLoadedData): void + private function readPrinterSettings(Spreadsheet $excel, string $dir, string $fileWorksheet, Worksheet $docSheet, array &$unparsedLoadedData): void { $zip = $this->zip; if (!$zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { @@ -2071,7 +2095,7 @@ class Xlsx extends BaseReader if ($xmlSheet && $xmlSheet->autoFilter) { // In older files, autofilter structure is defined in the worksheet file (new AutoFilter($docSheet, $xmlSheet))->load(); - } elseif ($xmlSheet && $xmlSheet->tableParts && $xmlSheet->tableParts['count'] > 0) { + } elseif ($xmlSheet && $xmlSheet->tableParts && (int) $xmlSheet->tableParts['count'] > 0) { // But for Office365, MS decided to make it all just a bit more complicated $this->readAutoFilterTablesInTablesFile($xmlSheet, $dir, $fileWorksheet, $zip, $docSheet); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php index 374da9f63..39328adb8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php @@ -9,8 +9,10 @@ use SimpleXMLElement; class AutoFilter { + /** @var Worksheet */ private $worksheet; + /** @var SimpleXMLElement */ private $worksheetXml; public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml) @@ -28,7 +30,7 @@ class AutoFilter } } - private function readAutoFilter($autoFilterRange, $xmlSheet): void + private function readAutoFilter(string $autoFilterRange, SimpleXMLElement $xmlSheet): void { $autoFilter = $this->worksheet->getAutoFilter(); $autoFilter->setRange($autoFilterRange); @@ -39,15 +41,15 @@ class AutoFilter if ($filterColumn->filters) { $column->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER); $filters = $filterColumn->filters; - if ((isset($filters['blank'])) && ($filters['blank'] == 1)) { + if ((isset($filters['blank'])) && ((int) $filters['blank'] == 1)) { // Operator is undefined, but always treated as EQUAL - $column->createRule()->setRule(null, '')->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER); + $column->createRule()->setRule('', '')->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER); } // Standard filters are always an OR join, so no join rule needs to be set // Entries can be either filter elements foreach ($filters->filter as $filterRule) { // Operator is undefined, but always treated as EQUAL - $column->createRule()->setRule(null, (string) $filterRule['val'])->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER); + $column->createRule()->setRule('', (string) $filterRule['val'])->setRuleType(Rule::AUTOFILTER_RULETYPE_FILTER); } // Or Date Group elements @@ -69,7 +71,7 @@ class AutoFilter foreach ($filters->dateGroupItem as $dateGroupItem) { // Operator is undefined, but always treated as EQUAL $column->createRule()->setRule( - null, + '', [ 'year' => (string) $dateGroupItem['year'], 'month' => (string) $dateGroupItem['month'], @@ -83,9 +85,9 @@ class AutoFilter } } - private function readCustomAutoFilter(SimpleXMLElement $filterColumn, Column $column): void + private function readCustomAutoFilter(?SimpleXMLElement $filterColumn, Column $column): void { - if ($filterColumn->customFilters) { + if (isset($filterColumn, $filterColumn->customFilters)) { $column->setFilterType(Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); $customFilters = $filterColumn->customFilters; // Custom filters can an AND or an OR join; @@ -102,15 +104,15 @@ class AutoFilter } } - private function readDynamicAutoFilter(SimpleXMLElement $filterColumn, Column $column): void + private function readDynamicAutoFilter(?SimpleXMLElement $filterColumn, Column $column): void { - if ($filterColumn->dynamicFilter) { + if (isset($filterColumn, $filterColumn->dynamicFilter)) { $column->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); // We should only ever have one dynamic filter foreach ($filterColumn->dynamicFilter as $filterRule) { // Operator is undefined, but always treated as EQUAL $column->createRule()->setRule( - null, + '', (string) $filterRule['val'], (string) $filterRule['type'] )->setRuleType(Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); @@ -124,9 +126,9 @@ class AutoFilter } } - private function readTopTenAutoFilter(SimpleXMLElement $filterColumn, Column $column): void + private function readTopTenAutoFilter(?SimpleXMLElement $filterColumn, Column $column): void { - if ($filterColumn->top10) { + if (isset($filterColumn, $filterColumn->top10)) { $column->setFilterType(Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); // We should only ever have one top10 filter foreach ($filterColumn->top10 as $filterRule) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php index 1679f01f9..2f1464582 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php @@ -4,7 +4,10 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; class BaseParserClass { - protected static function boolean($value) + /** + * @param mixed $value + */ + protected static function boolean($value): bool { if (is_object($value)) { $value = (string) $value; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php index cf77a7f25..c22334cac 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Chart.php @@ -11,8 +11,10 @@ use PhpOffice\PhpSpreadsheet\Chart\GridLines; use PhpOffice\PhpSpreadsheet\Chart\Layout; use PhpOffice\PhpSpreadsheet\Chart\Legend; use PhpOffice\PhpSpreadsheet\Chart\PlotArea; -use PhpOffice\PhpSpreadsheet\Chart\Properties; +use PhpOffice\PhpSpreadsheet\Chart\Properties as ChartProperties; use PhpOffice\PhpSpreadsheet\Chart\Title; +use PhpOffice\PhpSpreadsheet\Chart\TrendLine; +use PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Style\Font; use SimpleXMLElement; @@ -72,12 +74,34 @@ class Chart $rotX = $rotY = $rAngAx = $perspective = null; $xAxis = new Axis(); $yAxis = new Axis(); + $autoTitleDeleted = null; + $chartNoFill = false; + $gradientArray = []; + $gradientLin = null; + $roundedCorners = false; foreach ($chartElementsC as $chartElementKey => $chartElement) { switch ($chartElementKey) { + case 'spPr': + $possibleNoFill = $chartElementsC->spPr->children($this->aNamespace); + if (isset($possibleNoFill->noFill)) { + $chartNoFill = true; + } + + break; + case 'roundedCorners': + /** @var bool */ + $roundedCorners = self::getAttribute($chartElementsC->roundedCorners, 'val', 'boolean'); + + break; case 'chart': foreach ($chartElement as $chartDetailsKey => $chartDetails) { - $chartDetailsC = $chartDetails->children($this->cNamespace); + $chartDetails = Xlsx::testSimpleXml($chartDetails); switch ($chartDetailsKey) { + case 'autoTitleDeleted': + /** @var bool */ + $autoTitleDeleted = self::getAttribute($chartElementsC->chart->autoTitleDeleted, 'val', 'boolean'); + + break; case 'view3D': $rotX = self::getAttribute($chartDetails->rotX, 'val', 'integer'); $rotY = self::getAttribute($chartDetails->rotY, 'val', 'integer'); @@ -89,18 +113,42 @@ class Chart $plotAreaLayout = $XaxisLabel = $YaxisLabel = null; $plotSeries = $plotAttributes = []; $catAxRead = false; + $plotNoFill = false; foreach ($chartDetails as $chartDetailKey => $chartDetail) { + $chartDetail = Xlsx::testSimpleXml($chartDetail); switch ($chartDetailKey) { + case 'spPr': + $possibleNoFill = $chartDetails->spPr->children($this->aNamespace); + if (isset($possibleNoFill->noFill)) { + $plotNoFill = true; + } + if (isset($possibleNoFill->gradFill->gsLst)) { + foreach ($possibleNoFill->gradFill->gsLst->gs as $gradient) { + $gradient = Xlsx::testSimpleXml($gradient); + /** @var float */ + $pos = self::getAttribute($gradient, 'pos', 'float'); + $gradientArray[] = [ + $pos / ChartProperties::PERCENTAGE_MULTIPLIER, + new ChartColor($this->readColor($gradient)), + ]; + } + } + if (isset($possibleNoFill->gradFill->lin)) { + $gradientLin = ChartProperties::XmlToAngle((string) self::getAttribute($possibleNoFill->gradFill->lin, 'ang', 'string')); + } + + break; case 'layout': $plotAreaLayout = $this->chartLayoutDetails($chartDetail); break; - case 'catAx': + case Axis::AXIS_TYPE_CATEGORY: + case Axis::AXIS_TYPE_DATE: $catAxRead = true; if (isset($chartDetail->title)) { $XaxisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace)); } - $xAxis->setAxisType('catAx'); + $xAxis->setAxisType($chartDetailKey); $this->readEffects($chartDetail, $xAxis); if (isset($chartDetail->spPr)) { $sppr = $chartDetail->spPr->children($this->aNamespace); @@ -129,13 +177,7 @@ class Chart $this->setAxisProperties($chartDetail, $xAxis); break; - case 'dateAx': - if (isset($chartDetail->title)) { - $XaxisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace)); - } - - break; - case 'valAx': + case Axis::AXIS_TYPE_VALUE: $whichAxis = null; $axPos = null; if (isset($chartDetail->axPos)) { @@ -228,7 +270,7 @@ class Chart case 'doughnutChart': case 'pieChart': case 'pie3DChart': - $explosion = isset($chartDetail->ser->explosion); + $explosion = self::getAttribute($chartDetail->ser->explosion, 'val', 'string'); $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey); $plotSer->setPlotStyle("$explosion"); $plotSeries[] = $plotSer; @@ -272,7 +314,7 @@ class Chart break; case 'stockChart': $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey); - $plotAttributes = $this->readChartAttributes($plotAreaLayout); + $plotAttributes = $this->readChartAttributes($chartDetail); break; } @@ -282,6 +324,12 @@ class Chart } $plotArea = new PlotArea($plotAreaLayout, $plotSeries); $this->setChartAttributes($plotAreaLayout, $plotAttributes); + if ($plotNoFill) { + $plotArea->setNoFill(true); + } + if (!empty($gradientArray)) { + $plotArea->setGradientFillProperties($gradientArray, $gradientLin); + } break; case 'plotVisOnly': @@ -301,6 +349,7 @@ class Chart $legendLayout = null; $legendOverlay = false; foreach ($chartDetails as $chartDetailKey => $chartDetail) { + $chartDetail = Xlsx::testSimpleXml($chartDetail); switch ($chartDetailKey) { case 'legendPos': $legendPos = self::getAttribute($chartDetail, 'val', 'string'); @@ -324,6 +373,13 @@ class Chart } } $chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, (string) $dispBlanksAs, $XaxisLabel, $YaxisLabel, $xAxis, $yAxis); + if ($chartNoFill) { + $chart->setNoFill(true); + } + $chart->setRoundedCorners($roundedCorners); + if (is_bool($autoTitleDeleted)) { + $chart->setAutoTitleDeleted($autoTitleDeleted); + } if (is_int($rotX)) { $chart->setRotX($rotX); } @@ -345,14 +401,24 @@ class Chart $caption = []; $titleLayout = null; foreach ($titleDetails as $titleDetailKey => $chartDetail) { + $chartDetail = Xlsx::testSimpleXml($chartDetail); switch ($titleDetailKey) { case 'tx': - $titleDetails = $chartDetail->rich->children($this->aNamespace); - foreach ($titleDetails as $titleKey => $titleDetail) { - switch ($titleKey) { - case 'p': - $titleDetailPart = $titleDetail->children($this->aNamespace); - $caption[] = $this->parseRichText($titleDetailPart); + if (isset($chartDetail->rich)) { + $titleDetails = $chartDetail->rich->children($this->aNamespace); + foreach ($titleDetails as $titleKey => $titleDetail) { + $titleDetail = Xlsx::testSimpleXml($titleDetail); + switch ($titleKey) { + case 'p': + $titleDetailPart = $titleDetail->children($this->aNamespace); + $caption[] = $this->parseRichText($titleDetailPart); + } + } + } elseif (isset($chartDetail->strRef->strCache)) { + foreach ($chartDetail->strRef->strCache->pt as $pt) { + if (isset($pt->v)) { + $caption[] = (string) $pt->v; + } } } @@ -378,6 +444,7 @@ class Chart } $layout = []; foreach ($details as $detailKey => $detail) { + $detail = Xlsx::testSimpleXml($detail); $layout[$detailKey] = self::getAttribute($detail, 'val', 'string'); } @@ -404,12 +471,14 @@ class Chart $pointSize = null; $noFill = false; $bubble3D = false; - $dPtColors = []; + $dptColors = []; $markerFillColor = null; $markerBorderColor = null; $lineStyle = null; $labelLayout = null; + $trendLines = []; foreach ($seriesDetails as $seriesKey => $seriesDetail) { + $seriesDetail = Xlsx::testSimpleXml($seriesDetail); switch ($seriesKey) { case 'idx': $seriesIndex = self::getAttribute($seriesDetail, 'val', 'integer'); @@ -426,7 +495,6 @@ class Chart break; case 'spPr': $children = $seriesDetail->children($this->aNamespace); - $ln = $children->ln; if (isset($children->ln)) { $ln = $children->ln; if (is_countable($ln->noFill) && count($ln->noFill) === 1) { @@ -456,6 +524,41 @@ class Chart } } + break; + case 'trendline': + $trendLine = new TrendLine(); + $this->readLineStyle($seriesDetail, $trendLine); + /** @var ?string */ + $trendLineType = self::getAttribute($seriesDetail->trendlineType, 'val', 'string'); + /** @var ?bool */ + $dispRSqr = self::getAttribute($seriesDetail->dispRSqr, 'val', 'boolean'); + /** @var ?bool */ + $dispEq = self::getAttribute($seriesDetail->dispEq, 'val', 'boolean'); + /** @var ?int */ + $order = self::getAttribute($seriesDetail->order, 'val', 'integer'); + /** @var ?int */ + $period = self::getAttribute($seriesDetail->period, 'val', 'integer'); + /** @var ?float */ + $forward = self::getAttribute($seriesDetail->forward, 'val', 'float'); + /** @var ?float */ + $backward = self::getAttribute($seriesDetail->backward, 'val', 'float'); + /** @var ?float */ + $intercept = self::getAttribute($seriesDetail->intercept, 'val', 'float'); + /** @var ?string */ + $name = (string) $seriesDetail->name; + $trendLine->setTrendLineProperties( + $trendLineType, + $order, + $period, + $dispRSqr, + $dispEq, + $backward, + $forward, + $intercept, + $name + ); + $trendLines[] = $trendLine; + break; case 'marker': $marker = self::getAttribute($seriesDetail->symbol, 'val', 'string'); @@ -594,6 +697,17 @@ class Chart $seriesValues[$seriesIndex]->setSmoothLine(true); } } + if (!empty($trendLines)) { + if (isset($seriesLabel[$seriesIndex])) { + $seriesLabel[$seriesIndex]->setTrendLines($trendLines); + } + if (isset($seriesCategory[$seriesIndex])) { + $seriesCategory[$seriesIndex]->setTrendLines($trendLines); + } + if (isset($seriesValues[$seriesIndex])) { + $seriesValues[$seriesIndex]->setTrendLines($trendLines); + } + } } } /** @phpstan-ignore-next-line */ @@ -677,6 +791,7 @@ class Chart $pointCount = 0; foreach ($seriesValueSet as $seriesValueIdx => $seriesValue) { + $seriesValue = Xlsx::testSimpleXml($seriesValue); switch ($seriesValueIdx) { case 'ptCount': $pointCount = self::getAttribute($seriesValue, 'val', 'integer'); @@ -749,7 +864,6 @@ class Chart private function parseRichText(SimpleXMLElement $titleDetailPart): RichText { $value = new RichText(); - $objText = null; $defaultFontSize = null; $defaultBold = null; $defaultItalic = null; @@ -961,12 +1075,19 @@ class Chart } /** - * @param null|Layout|SimpleXMLElement $chartDetail + * @param ?SimpleXMLElement $chartDetail */ private function readChartAttributes($chartDetail): array { $plotAttributes = []; if (isset($chartDetail->dLbls)) { + if (isset($chartDetail->dLbls->dLblPos)) { + $plotAttributes['dLblPos'] = self::getAttribute($chartDetail->dLbls->dLblPos, 'val', 'string'); + } + if (isset($chartDetail->dLbls->numFmt)) { + $plotAttributes['numFmtCode'] = self::getAttribute($chartDetail->dLbls->numFmt, 'formatCode', 'string'); + $plotAttributes['numFmtLinked'] = self::getAttribute($chartDetail->dLbls->numFmt, 'sourceLinked', 'boolean'); + } if (isset($chartDetail->dLbls->showLegendKey)) { $plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); } @@ -1047,7 +1168,7 @@ class Chart } } - private function readEffects(SimpleXMLElement $chartDetail, ?Properties $chartObject): void + private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject): void { if (!isset($chartObject, $chartDetail->spPr)) { return; @@ -1055,7 +1176,7 @@ class Chart $sppr = $chartDetail->spPr->children($this->aNamespace); if (isset($sppr->effectLst->glow)) { - $axisGlowSize = (float) self::getAttribute($sppr->effectLst->glow, 'rad', 'integer') / Properties::POINTS_WIDTH_MULTIPLIER; + $axisGlowSize = (float) self::getAttribute($sppr->effectLst->glow, 'rad', 'integer') / ChartProperties::POINTS_WIDTH_MULTIPLIER; if ($axisGlowSize != 0.0) { $colorArray = $this->readColor($sppr->effectLst->glow); $chartObject->setGlowProperties($axisGlowSize, $colorArray['value'], $colorArray['alpha'], $colorArray['type']); @@ -1066,7 +1187,7 @@ class Chart /** @var string */ $softEdgeSize = self::getAttribute($sppr->effectLst->softEdge, 'rad', 'string'); if (is_numeric($softEdgeSize)) { - $chartObject->setSoftEdges((float) Properties::xmlToPoints($softEdgeSize)); + $chartObject->setSoftEdges((float) ChartProperties::xmlToPoints($softEdgeSize)); } } @@ -1081,20 +1202,20 @@ class Chart if ($type !== '') { /** @var string */ $blur = self::getAttribute($sppr->effectLst->$type, 'blurRad', 'string'); - $blur = is_numeric($blur) ? Properties::xmlToPoints($blur) : null; + $blur = is_numeric($blur) ? ChartProperties::xmlToPoints($blur) : null; /** @var string */ $dist = self::getAttribute($sppr->effectLst->$type, 'dist', 'string'); - $dist = is_numeric($dist) ? Properties::xmlToPoints($dist) : null; + $dist = is_numeric($dist) ? ChartProperties::xmlToPoints($dist) : null; /** @var string */ $direction = self::getAttribute($sppr->effectLst->$type, 'dir', 'string'); - $direction = is_numeric($direction) ? Properties::xmlToAngle($direction) : null; + $direction = is_numeric($direction) ? ChartProperties::xmlToAngle($direction) : null; $algn = self::getAttribute($sppr->effectLst->$type, 'algn', 'string'); $rot = self::getAttribute($sppr->effectLst->$type, 'rotWithShape', 'string'); $size = []; foreach (['sx', 'sy'] as $sizeType) { $sizeValue = self::getAttribute($sppr->effectLst->$type, $sizeType, 'string'); if (is_numeric($sizeValue)) { - $size[$sizeType] = Properties::xmlToTenthOfPercent((string) $sizeValue); + $size[$sizeType] = ChartProperties::xmlToTenthOfPercent((string) $sizeValue); } else { $size[$sizeType] = null; } @@ -1102,7 +1223,7 @@ class Chart foreach (['kx', 'ky'] as $sizeType) { $sizeValue = self::getAttribute($sppr->effectLst->$type, $sizeType, 'string'); if (is_numeric($sizeValue)) { - $size[$sizeType] = Properties::xmlToAngle((string) $sizeValue); + $size[$sizeType] = ChartProperties::xmlToAngle((string) $sizeValue); } else { $size[$sizeType] = null; } @@ -1131,6 +1252,7 @@ class Chart 'type' => null, 'value' => null, 'alpha' => null, + 'brightness' => null, ]; foreach (ChartColor::EXCEL_COLOR_TYPES as $type) { if (isset($colorXml->$type)) { @@ -1143,6 +1265,13 @@ class Chart $result['alpha'] = ChartColor::alphaFromXml($alpha); } } + if (isset($colorXml->$type->lumMod)) { + /** @var string */ + $brightness = self::getAttribute($colorXml->$type->lumMod, 'val', 'string'); + if (is_numeric($brightness)) { + $result['brightness'] = ChartColor::alphaFromXml($brightness); + } + } break; } @@ -1151,7 +1280,7 @@ class Chart return $result; } - private function readLineStyle(SimpleXMLElement $chartDetail, ?Properties $chartObject): void + private function readLineStyle(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject): void { if (!isset($chartObject, $chartDetail->spPr)) { return; @@ -1165,7 +1294,7 @@ class Chart /** @var string */ $lineWidthTemp = self::getAttribute($sppr->ln, 'w', 'string'); if (is_numeric($lineWidthTemp)) { - $lineWidth = Properties::xmlToPoints($lineWidthTemp); + $lineWidth = ChartProperties::xmlToPoints($lineWidthTemp); } /** @var string */ $compoundType = self::getAttribute($sppr->ln, 'cmpd', 'string'); @@ -1174,15 +1303,13 @@ class Chart /** @var string */ $capType = self::getAttribute($sppr->ln, 'cap', 'string'); if (isset($sppr->ln->miter)) { - $joinType = Properties::LINE_STYLE_JOIN_MITER; + $joinType = ChartProperties::LINE_STYLE_JOIN_MITER; } elseif (isset($sppr->ln->bevel)) { - $joinType = Properties::LINE_STYLE_JOIN_BEVEL; + $joinType = ChartProperties::LINE_STYLE_JOIN_BEVEL; } else { $joinType = ''; } - $headArrowType = ''; $headArrowSize = ''; - $endArrowType = ''; $endArrowSize = ''; /** @var string */ $headArrowType = self::getAttribute($sppr->ln->headEnd, 'type', 'string'); @@ -1220,6 +1347,9 @@ class Chart if (!isset($whichAxis)) { return; } + if (isset($chartDetail->delete)) { + $whichAxis->setAxisOption('hidden', (string) self::getAttribute($chartDetail->delete, 'val', 'string')); + } if (isset($chartDetail->numFmt)) { $whichAxis->setAxisNumberProperties( (string) self::getAttribute($chartDetail->numFmt, 'formatCode', 'string'), @@ -1263,5 +1393,24 @@ class Chart if (isset($chartDetail->minorUnit)) { $whichAxis->setAxisOption('minor_unit', (string) self::getAttribute($chartDetail->minorUnit, 'val', 'string')); } + if (isset($chartDetail->baseTimeUnit)) { + $whichAxis->setAxisOption('baseTimeUnit', (string) self::getAttribute($chartDetail->baseTimeUnit, 'val', 'string')); + } + if (isset($chartDetail->majorTimeUnit)) { + $whichAxis->setAxisOption('majorTimeUnit', (string) self::getAttribute($chartDetail->majorTimeUnit, 'val', 'string')); + } + if (isset($chartDetail->minorTimeUnit)) { + $whichAxis->setAxisOption('minorTimeUnit', (string) self::getAttribute($chartDetail->minorTimeUnit, 'val', 'string')); + } + if (isset($chartDetail->txPr)) { + $children = $chartDetail->txPr->children($this->aNamespace); + if (isset($children->bodyPr)) { + /** @var string */ + $textRotation = self::getAttribute($children->bodyPr, 'rot', 'string'); + if (is_numeric($textRotation)) { + $whichAxis->setAxisOption('textRotation', (string) ChartProperties::xmlToAngle($textRotation)); + } + } + } } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php index 2a1e2afd8..347057338 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php @@ -10,8 +10,10 @@ use SimpleXMLElement; class ColumnAndRowAttributes extends BaseParserClass { + /** @var Worksheet */ private $worksheet; + /** @var ?SimpleXMLElement */ private $worksheetXml; public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null) @@ -120,7 +122,7 @@ class ColumnAndRowAttributes extends BaseParserClass } } - private function isFilteredColumn(IReadFilter $readFilter, $columnCoordinate, array $rowsAttributes) + private function isFilteredColumn(IReadFilter $readFilter, string $columnCoordinate, array $rowsAttributes): bool { foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) { if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { @@ -131,7 +133,7 @@ class ColumnAndRowAttributes extends BaseParserClass return false; } - private function readColumnAttributes(SimpleXMLElement $worksheetCols, $readDataOnly) + private function readColumnAttributes(SimpleXMLElement $worksheetCols, bool $readDataOnly): array { $columnAttributes = []; @@ -151,7 +153,7 @@ class ColumnAndRowAttributes extends BaseParserClass return $columnAttributes; } - private function readColumnRangeAttributes(SimpleXMLElement $column, $readDataOnly) + private function readColumnRangeAttributes(SimpleXMLElement $column, bool $readDataOnly): array { $columnAttributes = []; @@ -172,7 +174,7 @@ class ColumnAndRowAttributes extends BaseParserClass return $columnAttributes; } - private function isFilteredRow(IReadFilter $readFilter, $rowCoordinate, array $columnsAttributes) + private function isFilteredRow(IReadFilter $readFilter, int $rowCoordinate, array $columnsAttributes): bool { foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) { if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { @@ -183,7 +185,7 @@ class ColumnAndRowAttributes extends BaseParserClass return false; } - private function readRowAttributes(SimpleXMLElement $worksheetRow, $readDataOnly) + private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly): array { $rowAttributes = []; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php index c631a0fe7..7d947bacf 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php @@ -10,11 +10,14 @@ use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormatValueO use PhpOffice\PhpSpreadsheet\Style\Style as Style; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; +use stdClass; class ConditionalStyles { + /** @var Worksheet */ private $worksheet; + /** @var SimpleXMLElement */ private $worksheetXml; /** @@ -22,6 +25,7 @@ class ConditionalStyles */ private $ns; + /** @var array */ private $dxfs; public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml, array $dxfs = []) @@ -146,7 +150,7 @@ class ConditionalStyles return $cfStyle; } - private function readConditionalStyles($xmlSheet): array + private function readConditionalStyles(SimpleXMLElement $xmlSheet): array { $conditionals = []; foreach ($xmlSheet->conditionalFormatting as $conditional) { @@ -162,7 +166,7 @@ class ConditionalStyles return $conditionals; } - private function setConditionalStyles(Worksheet $worksheet, array $conditionals, $xmlExtLst): void + private function setConditionalStyles(Worksheet $worksheet, array $conditionals, SimpleXMLElement $xmlExtLst): void { foreach ($conditionals as $cellRangeReference => $cfRules) { ksort($cfRules); @@ -176,7 +180,7 @@ class ConditionalStyles } } - private function readStyleRules($cfRules, $extLst) + private function readStyleRules(array $cfRules, SimpleXMLElement $extLst): array { $conditionalFormattingRuleExtensions = ConditionalFormattingRuleExtension::parseExtLstXml($extLst); $conditionalStyles = []; @@ -213,7 +217,7 @@ class ConditionalStyles if (isset($cfRule->dataBar)) { $objConditional->setDataBar( - $this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions) + $this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions) // @phpstan-ignore-line ); } else { $objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]); @@ -225,7 +229,10 @@ class ConditionalStyles return $conditionalStyles; } - private function readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions): ConditionalDataBar + /** + * @param SimpleXMLElement|stdClass $cfRule + */ + private function readDataBarOfConditionalRule($cfRule, array $conditionalFormattingRuleExtensions): ConditionalDataBar { $dataBar = new ConditionalDataBar(); //dataBar attribute @@ -257,7 +264,10 @@ class ConditionalStyles return $dataBar; } - private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, $cfRule, $conditionalFormattingRuleExtensions): void + /** + * @param SimpleXMLElement|stdClass $cfRule + */ + private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, $cfRule, array $conditionalFormattingRuleExtensions): void { if (isset($cfRule->extLst)) { $ns = $cfRule->extLst->getNamespaces(true); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php index b699cb574..dac76230c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php @@ -8,8 +8,10 @@ use SimpleXMLElement; class DataValidations { + /** @var Worksheet */ private $worksheet; + /** @var SimpleXMLElement */ private $worksheetXml; public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml) @@ -22,7 +24,7 @@ class DataValidations { foreach ($this->worksheetXml->dataValidations->dataValidation as $dataValidation) { // Uppercase coordinate - $range = strtoupper($dataValidation['sqref']); + $range = strtoupper((string) $dataValidation['sqref']); $rangeSet = explode(' ', $range); foreach ($rangeSet as $range) { $stRange = $this->worksheet->shrinkRangeToFit($range); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php index 848849962..7d48c7967 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php @@ -9,8 +9,10 @@ use SimpleXMLElement; class Hyperlinks { + /** @var Worksheet */ private $worksheet; + /** @var array */ private $hyperlinks = []; public function __construct(Worksheet $workSheet) diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php index 56f18f98b..08decd6e4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php @@ -8,8 +8,10 @@ use SimpleXMLElement; class PageSetup extends BaseParserClass { + /** @var Worksheet */ private $worksheet; + /** @var ?SimpleXMLElement */ private $worksheetXml; public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null) @@ -18,16 +20,17 @@ class PageSetup extends BaseParserClass $this->worksheetXml = $worksheetXml; } - public function load(array $unparsedLoadedData) + public function load(array $unparsedLoadedData): array { - if (!$this->worksheetXml) { + $worksheetXml = $this->worksheetXml; + if ($worksheetXml === null) { return $unparsedLoadedData; } - $this->margins($this->worksheetXml, $this->worksheet); - $unparsedLoadedData = $this->pageSetup($this->worksheetXml, $this->worksheet, $unparsedLoadedData); - $this->headerFooter($this->worksheetXml, $this->worksheet); - $this->pageBreaks($this->worksheetXml, $this->worksheet); + $this->margins($worksheetXml, $this->worksheet); + $unparsedLoadedData = $this->pageSetup($worksheetXml, $this->worksheet, $unparsedLoadedData); + $this->headerFooter($worksheetXml, $this->worksheet); + $this->pageBreaks($worksheetXml, $this->worksheet); return $unparsedLoadedData; } @@ -45,7 +48,7 @@ class PageSetup extends BaseParserClass } } - private function pageSetup(SimpleXMLElement $xmlSheet, Worksheet $worksheet, array $unparsedLoadedData) + private function pageSetup(SimpleXMLElement $xmlSheet, Worksheet $worksheet, array $unparsedLoadedData): array { if ($xmlSheet->pageSetup) { $docPageSetup = $worksheet->getPageSetup(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php index a302cc569..9c02da9f8 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php @@ -7,8 +7,10 @@ use SimpleXMLElement; class SheetViewOptions extends BaseParserClass { + /** @var Worksheet */ private $worksheet; + /** @var ?SimpleXMLElement */ private $worksheetXml; public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null) @@ -24,10 +26,11 @@ class SheetViewOptions extends BaseParserClass } if (isset($this->worksheetXml->sheetPr)) { - $this->tabColor($this->worksheetXml->sheetPr, $styleReader); - $this->codeName($this->worksheetXml->sheetPr); - $this->outlines($this->worksheetXml->sheetPr); - $this->pageSetup($this->worksheetXml->sheetPr); + $sheetPr = $this->worksheetXml->sheetPr; + $this->tabColor($sheetPr, $styleReader); + $this->codeName($sheetPr); + $this->outlines($sheetPr); + $this->pageSetup($sheetPr); } if (isset($this->worksheetXml->sheetFormatPr)) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php index 9d61e3d36..4743afbf9 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php @@ -29,7 +29,7 @@ class WorkbookView $this->spreadsheet->setActiveSheetIndex(0); $workbookView = $xmlWorkbook->children($mainNS)->bookViews->workbookView; - if (($readDataOnly !== true || !empty($this->loadSheetsOnly)) && !empty($workbookView)) { + if ($readDataOnly !== true && !empty($workbookView)) { $workbookViewAttributes = self::testSimpleXml(self::getAttributes($workbookView)); // active sheet index $activeTab = (int) $workbookViewAttributes->activeTab; // refers to old sheet index diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php index 0b5e0966c..d8f0d9dcd 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php @@ -18,6 +18,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use SimpleXMLElement; /** @@ -364,7 +365,7 @@ class Xml extends BaseReader $rowTo = $rowTo + $cell_ss['MergeDown']; } $cellRange .= ':' . $columnTo . $rowTo; - $spreadsheet->getActiveSheet()->mergeCells($cellRange); + $spreadsheet->getActiveSheet()->mergeCells($cellRange, Worksheet::MERGE_CELL_CONTENT_HIDE); } $hasCalculatedValue = false; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php index 08a38b3bb..3f53ed1d4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/ReferenceHelper.php @@ -253,10 +253,11 @@ class ReferenceHelper ? uksort($aDataValidationCollection, [self::class, 'cellReverseSort']) : uksort($aDataValidationCollection, [self::class, 'cellSort']); - foreach ($aDataValidationCollection as $cellAddress => $value) { + foreach ($aDataValidationCollection as $cellAddress => $dataValidation) { $newReference = $this->updateCellReference($cellAddress); if ($cellAddress !== $newReference) { - $worksheet->setDataValidation($newReference, $value); + $dataValidation->setSqref($newReference); + $worksheet->setDataValidation($newReference, $dataValidation); $worksheet->setDataValidation($cellAddress, null); } } @@ -537,11 +538,7 @@ class ReferenceHelper // Update workbook: define names if (count($worksheet->getParent()->getDefinedNames()) > 0) { - foreach ($worksheet->getParent()->getDefinedNames() as $definedName) { - if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) { - $definedName->setValue($this->updateCellReference($definedName->getValue())); - } - } + $this->updateDefinedNames($worksheet, $beforeCellAddress, $numberOfColumns, $numberOfRows); } // Garbage collect @@ -865,13 +862,13 @@ class ReferenceHelper } /** - * Update named formulas (i.e. containing worksheet references / named ranges). + * Update named formulae (i.e. containing worksheet references / named ranges). * * @param Spreadsheet $spreadsheet Object to update * @param string $oldName Old name (name to replace) * @param string $newName New name */ - public function updateNamedFormulas(Spreadsheet $spreadsheet, $oldName = '', $newName = ''): void + public function updateNamedFormulae(Spreadsheet $spreadsheet, $oldName = '', $newName = ''): void { if ($oldName == '') { return; @@ -880,7 +877,7 @@ class ReferenceHelper foreach ($spreadsheet->getWorksheetIterator() as $sheet) { foreach ($sheet->getCoordinates(false) as $coordinate) { $cell = $sheet->getCell($coordinate); - if (($cell !== null) && ($cell->getDataType() === DataType::TYPE_FORMULA)) { + if ($cell->getDataType() === DataType::TYPE_FORMULA) { $formula = $cell->getValue(); if (strpos($formula, $oldName) !== false) { $formula = str_replace("'" . $oldName . "'!", "'" . $newName . "'!", $formula); @@ -892,6 +889,40 @@ class ReferenceHelper } } + private function updateDefinedNames(Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void + { + foreach ($worksheet->getParent()->getDefinedNames() as $definedName) { + if ($definedName->isFormula() === false) { + $this->updateNamedRange($definedName, $worksheet, $beforeCellAddress, $numberOfColumns, $numberOfRows); + } else { + $this->updateNamedFormula($definedName, $worksheet, $beforeCellAddress, $numberOfColumns, $numberOfRows); + } + } + } + + private function updateNamedRange(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void + { + $cellAddress = $definedName->getValue(); + $asFormula = ($cellAddress[0] === '='); + if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) { + if ($asFormula === true) { + $formula = $this->updateFormulaReferences($cellAddress, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle()); + $definedName->setValue($formula); + } else { + $definedName->setValue($this->updateCellReference(ltrim($cellAddress, '='))); + } + } + } + + private function updateNamedFormula(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void + { + if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) { + $formula = $definedName->getValue(); + $formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle()); + $definedName->setValue($formula); + } + } + /** * Update cell range. * diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php index 5fbbadb67..3282a596e 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php @@ -8,6 +8,7 @@ use PhpOffice\PhpSpreadsheet\Collection\Memory; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\SimpleCache\CacheInterface; +use ReflectionClass; class Settings { @@ -161,12 +162,19 @@ class Settings public static function getCache(): CacheInterface { if (!self::$cache) { - self::$cache = new Memory(); + self::$cache = self::useSimpleCacheVersion3() ? new Memory\SimpleCache3() : new Memory\SimpleCache1(); } return self::$cache; } + public static function useSimpleCacheVersion3(): bool + { + return + PHP_MAJOR_VERSION === 8 && + (new ReflectionClass(CacheInterface::class))->getMethod('get')->getReturnType() !== null; + } + /** * Set the HTTP client implementation to be used for network request. */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php index 1adf213ec..e90c679b6 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Font.php @@ -13,7 +13,7 @@ class Font const AUTOSIZE_METHOD_APPROX = 'approx'; const AUTOSIZE_METHOD_EXACT = 'exact'; - private static $autoSizeMethods = [ + private const AUTOSIZE_METHODS = [ self::AUTOSIZE_METHOD_APPROX, self::AUTOSIZE_METHOD_EXACT, ]; @@ -101,6 +101,105 @@ class Font const VERDANA_ITALIC = 'verdanai.ttf'; const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; + const FONT_FILE_NAMES = [ + 'Arial' => [ + 'x' => self::ARIAL, + 'xb' => self::ARIAL_BOLD, + 'xi' => self::ARIAL_ITALIC, + 'xbi' => self::ARIAL_BOLD_ITALIC, + ], + 'Calibri' => [ + 'x' => self::CALIBRI, + 'xb' => self::CALIBRI_BOLD, + 'xi' => self::CALIBRI_ITALIC, + 'xbi' => self::CALIBRI_BOLD_ITALIC, + ], + 'Comic Sans MS' => [ + 'x' => self::COMIC_SANS_MS, + 'xb' => self::COMIC_SANS_MS_BOLD, + 'xi' => self::COMIC_SANS_MS, + 'xbi' => self::COMIC_SANS_MS_BOLD, + ], + 'Courier New' => [ + 'x' => self::COURIER_NEW, + 'xb' => self::COURIER_NEW_BOLD, + 'xi' => self::COURIER_NEW_ITALIC, + 'xbi' => self::COURIER_NEW_BOLD_ITALIC, + ], + 'Georgia' => [ + 'x' => self::GEORGIA, + 'xb' => self::GEORGIA_BOLD, + 'xi' => self::GEORGIA_ITALIC, + 'xbi' => self::GEORGIA_BOLD_ITALIC, + ], + 'Impact' => [ + 'x' => self::IMPACT, + 'xb' => self::IMPACT, + 'xi' => self::IMPACT, + 'xbi' => self::IMPACT, + ], + 'Liberation Sans' => [ + 'x' => self::LIBERATION_SANS, + 'xb' => self::LIBERATION_SANS_BOLD, + 'xi' => self::LIBERATION_SANS_ITALIC, + 'xbi' => self::LIBERATION_SANS_BOLD_ITALIC, + ], + 'Lucida Console' => [ + 'x' => self::LUCIDA_CONSOLE, + 'xb' => self::LUCIDA_CONSOLE, + 'xi' => self::LUCIDA_CONSOLE, + 'xbi' => self::LUCIDA_CONSOLE, + ], + 'Lucida Sans Unicode' => [ + 'x' => self::LUCIDA_SANS_UNICODE, + 'xb' => self::LUCIDA_SANS_UNICODE, + 'xi' => self::LUCIDA_SANS_UNICODE, + 'xbi' => self::LUCIDA_SANS_UNICODE, + ], + 'Microsoft Sans Serif' => [ + 'x' => self::MICROSOFT_SANS_SERIF, + 'xb' => self::MICROSOFT_SANS_SERIF, + 'xi' => self::MICROSOFT_SANS_SERIF, + 'xbi' => self::MICROSOFT_SANS_SERIF, + ], + 'Palatino Linotype' => [ + 'x' => self::PALATINO_LINOTYPE, + 'xb' => self::PALATINO_LINOTYPE_BOLD, + 'xi' => self::PALATINO_LINOTYPE_ITALIC, + 'xbi' => self::PALATINO_LINOTYPE_BOLD_ITALIC, + ], + 'Symbol' => [ + 'x' => self::SYMBOL, + 'xb' => self::SYMBOL, + 'xi' => self::SYMBOL, + 'xbi' => self::SYMBOL, + ], + 'Tahoma' => [ + 'x' => self::TAHOMA, + 'xb' => self::TAHOMA_BOLD, + 'xi' => self::TAHOMA, + 'xbi' => self::TAHOMA_BOLD, + ], + 'Times New Roman' => [ + 'x' => self::TIMES_NEW_ROMAN, + 'xb' => self::TIMES_NEW_ROMAN_BOLD, + 'xi' => self::TIMES_NEW_ROMAN_ITALIC, + 'xbi' => self::TIMES_NEW_ROMAN_BOLD_ITALIC, + ], + 'Trebuchet MS' => [ + 'x' => self::TREBUCHET_MS, + 'xb' => self::TREBUCHET_MS_BOLD, + 'xi' => self::TREBUCHET_MS_ITALIC, + 'xbi' => self::TREBUCHET_MS_BOLD_ITALIC, + ], + 'Verdana' => [ + 'x' => self::VERDANA, + 'xb' => self::VERDANA_BOLD, + 'xi' => self::VERDANA_ITALIC, + 'xbi' => self::VERDANA_BOLD_ITALIC, + ], + ]; + /** * AutoSize method. * @@ -113,54 +212,65 @@ class Font * * @var string */ - private static $trueTypeFontPath; + private static $trueTypeFontPath = ''; /** * How wide is a default column for a given default font and size? * Empirical data found by inspecting real Excel files and reading off the pixel width * in Microsoft Office Excel 2007. + * Added height in points. + */ + public const DEFAULT_COLUMN_WIDTHS = [ + 'Arial' => [ + 1 => ['px' => 24, 'width' => 12.00000000, 'height' => 5.25], + 2 => ['px' => 24, 'width' => 12.00000000, 'height' => 5.25], + 3 => ['px' => 32, 'width' => 10.66406250, 'height' => 6.0], + + 4 => ['px' => 32, 'width' => 10.66406250, 'height' => 6.75], + 5 => ['px' => 40, 'width' => 10.00000000, 'height' => 8.25], + 6 => ['px' => 48, 'width' => 9.59765625, 'height' => 8.25], + 7 => ['px' => 48, 'width' => 9.59765625, 'height' => 9.0], + 8 => ['px' => 56, 'width' => 9.33203125, 'height' => 11.25], + 9 => ['px' => 64, 'width' => 9.14062500, 'height' => 12.0], + 10 => ['px' => 64, 'width' => 9.14062500, 'height' => 12.75], + ], + 'Calibri' => [ + 1 => ['px' => 24, 'width' => 12.00000000, 'height' => 5.25], + 2 => ['px' => 24, 'width' => 12.00000000, 'height' => 5.25], + 3 => ['px' => 32, 'width' => 10.66406250, 'height' => 6.00], + 4 => ['px' => 32, 'width' => 10.66406250, 'height' => 6.75], + 5 => ['px' => 40, 'width' => 10.00000000, 'height' => 8.25], + 6 => ['px' => 48, 'width' => 9.59765625, 'height' => 8.25], + 7 => ['px' => 48, 'width' => 9.59765625, 'height' => 9.0], + 8 => ['px' => 56, 'width' => 9.33203125, 'height' => 11.25], + 9 => ['px' => 56, 'width' => 9.33203125, 'height' => 12.0], + 10 => ['px' => 64, 'width' => 9.14062500, 'height' => 12.75], + 11 => ['px' => 64, 'width' => 9.14062500, 'height' => 15.0], + ], + 'Verdana' => [ + 1 => ['px' => 24, 'width' => 12.00000000, 'height' => 5.25], + 2 => ['px' => 24, 'width' => 12.00000000, 'height' => 5.25], + 3 => ['px' => 32, 'width' => 10.66406250, 'height' => 6.0], + 4 => ['px' => 32, 'width' => 10.66406250, 'height' => 6.75], + 5 => ['px' => 40, 'width' => 10.00000000, 'height' => 8.25], + 6 => ['px' => 48, 'width' => 9.59765625, 'height' => 8.25], + 7 => ['px' => 48, 'width' => 9.59765625, 'height' => 9.0], + 8 => ['px' => 64, 'width' => 9.14062500, 'height' => 10.5], + 9 => ['px' => 72, 'width' => 9.00000000, 'height' => 11.25], + 10 => ['px' => 72, 'width' => 9.00000000, 'height' => 12.75], + ], + ]; + + /** + * List of column widths. Replaced by constant; + * previously it was public and updateable, allowing + * user to make inappropriate alterations. + * + * @deprecated 1.25.0 Use DEFAULT_COLUMN_WIDTHS constant instead. * * @var array */ - public static $defaultColumnWidths = [ - 'Arial' => [ - 1 => ['px' => 24, 'width' => 12.00000000], - 2 => ['px' => 24, 'width' => 12.00000000], - 3 => ['px' => 32, 'width' => 10.66406250], - 4 => ['px' => 32, 'width' => 10.66406250], - 5 => ['px' => 40, 'width' => 10.00000000], - 6 => ['px' => 48, 'width' => 9.59765625], - 7 => ['px' => 48, 'width' => 9.59765625], - 8 => ['px' => 56, 'width' => 9.33203125], - 9 => ['px' => 64, 'width' => 9.14062500], - 10 => ['px' => 64, 'width' => 9.14062500], - ], - 'Calibri' => [ - 1 => ['px' => 24, 'width' => 12.00000000], - 2 => ['px' => 24, 'width' => 12.00000000], - 3 => ['px' => 32, 'width' => 10.66406250], - 4 => ['px' => 32, 'width' => 10.66406250], - 5 => ['px' => 40, 'width' => 10.00000000], - 6 => ['px' => 48, 'width' => 9.59765625], - 7 => ['px' => 48, 'width' => 9.59765625], - 8 => ['px' => 56, 'width' => 9.33203125], - 9 => ['px' => 56, 'width' => 9.33203125], - 10 => ['px' => 64, 'width' => 9.14062500], - 11 => ['px' => 64, 'width' => 9.14062500], - ], - 'Verdana' => [ - 1 => ['px' => 24, 'width' => 12.00000000], - 2 => ['px' => 24, 'width' => 12.00000000], - 3 => ['px' => 32, 'width' => 10.66406250], - 4 => ['px' => 32, 'width' => 10.66406250], - 5 => ['px' => 40, 'width' => 10.00000000], - 6 => ['px' => 48, 'width' => 9.59765625], - 7 => ['px' => 48, 'width' => 9.59765625], - 8 => ['px' => 64, 'width' => 9.14062500], - 9 => ['px' => 72, 'width' => 9.00000000], - 10 => ['px' => 72, 'width' => 9.00000000], - ], - ]; + public static $defaultColumnWidths = self::DEFAULT_COLUMN_WIDTHS; /** * Set autoSize method. @@ -171,7 +281,7 @@ class Font */ public static function setAutoSizeMethod($method) { - if (!in_array($method, self::$autoSizeMethods)) { + if (!in_array($method, self::AUTOSIZE_METHODS)) { return false; } self::$autoSizeMethod = $method; @@ -219,7 +329,7 @@ class Font * Calculate an (approximate) OpenXML column width, based on font size and text contained. * * @param FontStyle $font Font object - * @param RichText|string $cellText Text to calculate width + * @param null|RichText|string $cellText Text to calculate width * @param int $rotation Rotation angle * @param null|FontStyle $defaultFont Font object * @param bool $filterAdjustment Add space for Autofilter or Table dropdown @@ -238,7 +348,8 @@ class Font } // Special case if there are one or more newline characters ("\n") - if (strpos($cellText ?? '', "\n") !== false) { + $cellText = $cellText ?? ''; + if (strpos(/** @scrutinizer ignore-type */ $cellText, "\n") !== false) { $lineTexts = explode("\n", $cellText); $lineWidths = []; foreach ($lineTexts as $lineText) { @@ -281,7 +392,7 @@ class Font } // Convert from pixel width to column width - $columnWidth = Drawing::pixelsToCellDimension((int) $columnWidth, $defaultFont); + $columnWidth = Drawing::pixelsToCellDimension((int) $columnWidth, $defaultFont ?? new FontStyle()); // Return return (int) round($columnWidth, 6); @@ -299,7 +410,12 @@ class Font // font size should really be supplied in pixels in GD2, // but since GD2 seems to assume 72dpi, pixels and points are the same $fontFile = self::getTrueTypeFontFileFromFont($font); - $textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text); + $textBox = imagettfbbox($font->getSize() ?? 10.0, $rotation, $fontFile, $text); + if ($textBox === false) { + // @codeCoverageIgnoreStart + throw new PhpSpreadsheetException('imagettfbbox failed'); + // @codeCoverageIgnoreEnd + } // Get corners positions $lowerLeftCornerX = $textBox[0]; @@ -409,129 +525,48 @@ class Font * * @return string Path to TrueType font file */ - public static function getTrueTypeFontFileFromFont(FontStyle $font) + public static function getTrueTypeFontFileFromFont(FontStyle $font, bool $checkPath = true) { - if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) { + if ($checkPath && (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath))) { throw new PhpSpreadsheetException('Valid directory to TrueType Font files not specified'); } $name = $font->getName(); + if (!isset(self::FONT_FILE_NAMES[$name])) { + throw new PhpSpreadsheetException('Unknown font name "' . $name . '". Cannot map to TrueType font file'); + } $bold = $font->getBold(); $italic = $font->getItalic(); - - // Check if we can map font to true type font file - switch ($name) { - case 'Arial': - $fontFile = ( - $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD) - : ($italic ? self::ARIAL_ITALIC : self::ARIAL) - ); - - break; - case 'Calibri': - $fontFile = ( - $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) - : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) - ); - - break; - case 'Courier New': - $fontFile = ( - $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) - : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) - ); - - break; - case 'Comic Sans MS': - $fontFile = ( - $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS - ); - - break; - case 'Georgia': - $fontFile = ( - $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) - : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) - ); - - break; - case 'Impact': - $fontFile = self::IMPACT; - - break; - case 'Liberation Sans': - $fontFile = ( - $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) - : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) - ); - - break; - case 'Lucida Console': - $fontFile = self::LUCIDA_CONSOLE; - - break; - case 'Lucida Sans Unicode': - $fontFile = self::LUCIDA_SANS_UNICODE; - - break; - case 'Microsoft Sans Serif': - $fontFile = self::MICROSOFT_SANS_SERIF; - - break; - case 'Palatino Linotype': - $fontFile = ( - $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) - : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) - ); - - break; - case 'Symbol': - $fontFile = self::SYMBOL; - - break; - case 'Tahoma': - $fontFile = ( - $bold ? self::TAHOMA_BOLD : self::TAHOMA - ); - - break; - case 'Times New Roman': - $fontFile = ( - $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) - : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) - ); - - break; - case 'Trebuchet MS': - $fontFile = ( - $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) - : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) - ); - - break; - case 'Verdana': - $fontFile = ( - $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) - : ($italic ? self::VERDANA_ITALIC : self::VERDANA) - ); - - break; - default: - throw new PhpSpreadsheetException('Unknown font name "' . $name . '". Cannot map to TrueType font file'); - - break; + $index = 'x'; + if ($bold) { + $index .= 'b'; } + if ($italic) { + $index .= 'i'; + } + $fontFile = self::FONT_FILE_NAMES[$name][$index]; - $fontFile = self::$trueTypeFontPath . $fontFile; + $separator = ''; + if (mb_strlen(self::$trueTypeFontPath) > 1 && mb_substr(self::$trueTypeFontPath, -1) !== '/' && mb_substr(self::$trueTypeFontPath, -1) !== '\\') { + $separator = DIRECTORY_SEPARATOR; + } + $fontFile = self::$trueTypeFontPath . $separator . $fontFile; // Check if file actually exists - if (!file_exists($fontFile)) { + if ($checkPath && !file_exists($fontFile)) { throw new PhpSpreadsheetException('TrueType Font file not found'); } return $fontFile; } + public const CHARSET_FROM_FONT_NAME = [ + 'EucrosiaUPC' => self::CHARSET_ANSI_THAI, + 'Wingdings' => self::CHARSET_SYMBOL, + 'Wingdings 2' => self::CHARSET_SYMBOL, + 'Wingdings 3' => self::CHARSET_SYMBOL, + ]; + /** * Returns the associated charset for the font name. * @@ -541,19 +576,7 @@ class Font */ public static function getCharsetFromFontName($fontName) { - switch ($fontName) { - // Add more cases. Check FONT records in real Excel files. - case 'EucrosiaUPC': - return self::CHARSET_ANSI_THAI; - case 'Wingdings': - return self::CHARSET_SYMBOL; - case 'Wingdings 2': - return self::CHARSET_SYMBOL; - case 'Wingdings 3': - return self::CHARSET_SYMBOL; - default: - return self::CHARSET_ANSI_LATIN; - } + return self::CHARSET_FROM_FONT_NAME[$fontName] ?? self::CHARSET_ANSI_LATIN; } /** @@ -567,17 +590,17 @@ class Font */ public static function getDefaultColumnWidthByFont(FontStyle $font, $returnAsPixels = false) { - if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) { + if (isset(self::DEFAULT_COLUMN_WIDTHS[$font->getName()][$font->getSize()])) { // Exact width can be determined $columnWidth = $returnAsPixels ? - self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px'] - : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width']; + self::DEFAULT_COLUMN_WIDTHS[$font->getName()][$font->getSize()]['px'] + : self::DEFAULT_COLUMN_WIDTHS[$font->getName()][$font->getSize()]['width']; } else { // We don't have data for this particular font and size, use approximation by // extrapolating from Calibri 11 $columnWidth = $returnAsPixels ? - self::$defaultColumnWidths['Calibri'][11]['px'] - : self::$defaultColumnWidths['Calibri'][11]['width']; + self::DEFAULT_COLUMN_WIDTHS['Calibri'][11]['px'] + : self::DEFAULT_COLUMN_WIDTHS['Calibri'][11]['width']; $columnWidth = $columnWidth * $font->getSize() / 11; // Round pixels to closest integer @@ -599,173 +622,14 @@ class Font */ public static function getDefaultRowHeightByFont(FontStyle $font) { - switch ($font->getName()) { - case 'Arial': - switch ($font->getSize()) { - case 10: - // inspection of Arial 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - - break; - case 9: - // inspection of Arial 9 workbook says 12.00pt ~16px - $rowHeight = 12; - - break; - case 8: - // inspection of Arial 8 workbook says 11.25pt ~15px - $rowHeight = 11.25; - - break; - case 7: - // inspection of Arial 7 workbook says 9.00pt ~12px - $rowHeight = 9; - - break; - case 6: - case 5: - // inspection of Arial 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - - break; - case 4: - // inspection of Arial 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - - break; - case 3: - // inspection of Arial 3 workbook says 6.00pt ~8px - $rowHeight = 6; - - break; - case 2: - case 1: - // inspection of Arial 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - - break; - default: - // use Arial 10 workbook as an approximation, extrapolation - $rowHeight = 12.75 * $font->getSize() / 10; - - break; - } - - break; - case 'Calibri': - switch ($font->getSize()) { - case 11: - // inspection of Calibri 11 workbook says 15.00pt ~20px - $rowHeight = 15; - - break; - case 10: - // inspection of Calibri 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - - break; - case 9: - // inspection of Calibri 9 workbook says 12.00pt ~16px - $rowHeight = 12; - - break; - case 8: - // inspection of Calibri 8 workbook says 11.25pt ~15px - $rowHeight = 11.25; - - break; - case 7: - // inspection of Calibri 7 workbook says 9.00pt ~12px - $rowHeight = 9; - - break; - case 6: - case 5: - // inspection of Calibri 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - - break; - case 4: - // inspection of Calibri 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - - break; - case 3: - // inspection of Calibri 3 workbook says 6.00pt ~8px - $rowHeight = 6.00; - - break; - case 2: - case 1: - // inspection of Calibri 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - - break; - default: - // use Calibri 11 workbook as an approximation, extrapolation - $rowHeight = 15 * $font->getSize() / 11; - - break; - } - - break; - case 'Verdana': - switch ($font->getSize()) { - case 10: - // inspection of Verdana 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - - break; - case 9: - // inspection of Verdana 9 workbook says 11.25pt ~15px - $rowHeight = 11.25; - - break; - case 8: - // inspection of Verdana 8 workbook says 10.50pt ~14px - $rowHeight = 10.50; - - break; - case 7: - // inspection of Verdana 7 workbook says 9.00pt ~12px - $rowHeight = 9.00; - - break; - case 6: - case 5: - // inspection of Verdana 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - - break; - case 4: - // inspection of Verdana 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - - break; - case 3: - // inspection of Verdana 3 workbook says 6.00pt ~8px - $rowHeight = 6; - - break; - case 2: - case 1: - // inspection of Verdana 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - - break; - default: - // use Verdana 10 workbook as an approximation, extrapolation - $rowHeight = 12.75 * $font->getSize() / 10; - - break; - } - - break; - default: - // just use Calibri as an approximation - $rowHeight = 15 * $font->getSize() / 11; - - break; + $name = $font->getName(); + $size = $font->getSize(); + if (isset(self::DEFAULT_COLUMN_WIDTHS[$name][$size])) { + $rowHeight = self::DEFAULT_COLUMN_WIDTHS[$name][$size]['height']; + } elseif ($name === 'Arial' || $name === 'Verdana') { + $rowHeight = self::DEFAULT_COLUMN_WIDTHS[$name][10]['height'] * $size / 10.0; + } else { + $rowHeight = self::DEFAULT_COLUMN_WIDTHS['Calibri'][11]['height'] * $size / 11.0; } return $rowHeight; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php index 66111b6c8..1ec7f6abf 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php @@ -495,7 +495,7 @@ class EigenvalueDecomposition $this->V[$i][$n - 1] = $q * $z + $p * $this->V[$i][$n]; $this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z; } - // Complex pair + // Complex pair } else { $this->d[$n - 1] = $x + $p; $this->d[$n] = $x + $p; @@ -671,7 +671,7 @@ class EigenvalueDecomposition } else { $this->H[$i][$n] = -$r / ($eps * $norm); } - // Solve real equations + // Solve real equations } else { $x = $this->H[$i][$i + 1]; $y = $this->H[$i + 1][$i]; @@ -693,7 +693,7 @@ class EigenvalueDecomposition } } } - // Complex vector + // Complex vector } elseif ($q < 0) { $l = $n - 1; // Last vector component imaginary so matrix is triangular diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php index ab78ef18c..5e35d4919 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Shared\JAMA; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; @@ -66,21 +67,21 @@ class Matrix $this->A = $args[0]; break; - //Square matrix - n x n + //Square matrix - n x n case 'integer': $this->m = $args[0]; $this->n = $args[0]; $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); break; - //Rectangular matrix - m x n + //Rectangular matrix - m x n case 'integer,integer': $this->m = $args[0]; $this->n = $args[1]; $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); break; - //Rectangular matrix - m x n initialized from packed array + //Rectangular matrix - m x n initialized from packed array case 'array,integer': $this->m = $args[1]; if ($this->m != 0) { @@ -190,7 +191,7 @@ class Matrix return $R; break; - //A($i0...$iF; $j0...$jF) + //A($i0...$iF; $j0...$jF) case 'integer,integer,integer,integer': [$i0, $iF, $j0, $jF] = $args; if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { @@ -213,7 +214,7 @@ class Matrix return $R; break; - //$R = array of row indices; $C = array of column indices + //$R = array of row indices; $C = array of column indices case 'array,array': [$RL, $CL] = $args; if (count($RL) > 0) { @@ -236,7 +237,7 @@ class Matrix return $R; break; - //A($i0...$iF); $CL = array of column indices + //A($i0...$iF); $CL = array of column indices case 'integer,integer,array': [$i0, $iF, $CL] = $args; if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { @@ -259,7 +260,7 @@ class Matrix return $R; break; - //$RL = array of row indices + //$RL = array of row indices case 'array,integer,integer': [$RL, $j0, $jF] = $args; if (count($RL) > 0) { @@ -532,14 +533,8 @@ class Matrix for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j], '"'); - $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value, '"'); - $validValues &= StringHelper::convertToNumberIfFraction($value); - } + [$this->A[$i][$j], $validValues] = $this->validateExtractedValue($this->A[$i][$j], $validValues); + [$value, $validValues] = $this->validateExtractedValue($value, $validValues); if ($validValues) { $this->A[$i][$j] += $value; } else { @@ -632,14 +627,8 @@ class Matrix for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j], '"'); - $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value, '"'); - $validValues &= StringHelper::convertToNumberIfFraction($value); - } + [$this->A[$i][$j], $validValues] = $this->validateExtractedValue($this->A[$i][$j], $validValues); + [$value, $validValues] = $this->validateExtractedValue($value, $validValues); if ($validValues) { $this->A[$i][$j] -= $value; } else { @@ -734,14 +723,8 @@ class Matrix for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j], '"'); - $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value, '"'); - $validValues &= StringHelper::convertToNumberIfFraction($value); - } + [$this->A[$i][$j], $validValues] = $this->validateExtractedValue($this->A[$i][$j], $validValues); + [$value, $validValues] = $this->validateExtractedValue($value, $validValues); if ($validValues) { $this->A[$i][$j] *= $value; } else { @@ -792,14 +775,8 @@ class Matrix for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j], '"'); - $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value, '"'); - $validValues &= StringHelper::convertToNumberIfFraction($value); - } + [$this->A[$i][$j], $validValues] = $this->validateExtractedValue($this->A[$i][$j], $validValues); + [$value, $validValues] = $this->validateExtractedValue($value, $validValues); if ($validValues) { if ($value == 0) { // Trap for Divide by Zero error @@ -1079,14 +1056,8 @@ class Matrix for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j], '"'); - $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value, '"'); - $validValues &= StringHelper::convertToNumberIfFraction($value); - } + [$this->A[$i][$j], $validValues] = $this->validateExtractedValue($this->A[$i][$j], $validValues); + [$value, $validValues] = $this->validateExtractedValue($value, $validValues); if ($validValues) { $this->A[$i][$j] = $this->A[$i][$j] ** $value; } else { @@ -1187,4 +1158,20 @@ class Matrix return $L->det(); } + + /** + * @param mixed $value + */ + private function validateExtractedValue($value, bool $validValues): array + { + if (!is_numeric($value) && is_array($value)) { + $value = Functions::flattenArray($value)[0]; + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value, '"'); + $validValues &= StringHelper::convertToNumberIfFraction($value); + } + + return [$value, $validValues]; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php index 6c8999d02..b809bfa1d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php @@ -315,7 +315,7 @@ class SingularValueDecomposition } break; - // Split at negligible s(k). + // Split at negligible s(k). case 2: $f = $e[$k - 1]; $e[$k - 1] = 0.0; @@ -336,7 +336,7 @@ class SingularValueDecomposition } break; - // Perform one qr step. + // Perform one qr step. case 3: // Calculate the shift. $scale = max(max(max(max(abs($this->s[$p - 1]), abs($this->s[$p - 2])), abs($e[$p - 2])), abs($this->s[$k])), abs($e[$k])); @@ -396,7 +396,7 @@ class SingularValueDecomposition $iter = $iter + 1; break; - // Convergence. + // Convergence. case 4: // Make the singular values positive. if ($this->s[$k] <= 0.0) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php index 030df66df..16026c3ca 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheet\Shared; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use UConverter; class StringHelper { @@ -334,26 +333,23 @@ class StringHelper public static function sanitizeUTF8(string $textValue): string { $textValue = str_replace(["\xef\xbf\xbe", "\xef\xbf\xbf"], "\xef\xbf\xbd", $textValue); - if (class_exists(UConverter::class)) { - $returnValue = UConverter::transcode($textValue, 'UTF-8', 'UTF-8'); - if ($returnValue !== false) { - return $returnValue; - } - } - // @codeCoverageIgnoreStart - // I don't think any of the code below should ever be executed. - if (self::getIsIconvEnabled()) { - $returnValue = @iconv('UTF-8', 'UTF-8', $textValue); - if ($returnValue !== false) { - return $returnValue; - } - } - + $subst = mb_substitute_character(); // default is question mark + mb_substitute_character(65533); // Unicode substitution character // Phpstan does not think this can return false. $returnValue = mb_convert_encoding($textValue, 'UTF-8', 'UTF-8'); + mb_substitute_character(/** @scrutinizer ignore-type */ $subst); - return $returnValue; - // @codeCoverageIgnoreEnd + return self::returnString($returnValue); + } + + /** + * Strictly to satisfy Scrutinizer. + * + * @param mixed $value + */ + private static function returnString($value): string + { + return is_string($value) ? $value : ''; } /** @@ -447,7 +443,7 @@ class StringHelper } } - return mb_convert_encoding($textValue, $to, $from); + return self::returnString(mb_convert_encoding($textValue, $to, $from)); } /** diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php index 33b4fe0c4..364700e25 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php @@ -3,10 +3,13 @@ namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader; +use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Iterator; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter; class Spreadsheet { @@ -721,6 +724,19 @@ class Spreadsheet return null; } + /** + * Get sheet by name, throwing exception if not found. + */ + public function getSheetByNameOrThrow(string $worksheetName): Worksheet + { + $worksheet = $this->getSheetByName($worksheetName); + if ($worksheet === null) { + throw new Exception("Sheet $worksheetName does not exist."); + } + + return $worksheet; + } + /** * Get index for sheet. * @@ -1120,28 +1136,24 @@ class Spreadsheet */ public function copy() { - $copied = clone $this; + $filename = File::temporaryFilename(); + $writer = new XlsxWriter($this); + $writer->setIncludeCharts(true); + $writer->save($filename); - $worksheetCount = count($this->workSheetCollection); - for ($i = 0; $i < $worksheetCount; ++$i) { - $this->workSheetCollection[$i] = $this->workSheetCollection[$i]->copy(); - $this->workSheetCollection[$i]->rebindParent($this); - } + $reader = new XlsxReader(); + $reader->setIncludeCharts(true); + $reloadedSpreadsheet = $reader->load($filename); + unlink($filename); - return $copied; + return $reloadedSpreadsheet; } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ public function __clone() { - // @phpstan-ignore-next-line - foreach ($this as $key => $val) { - if (is_object($val) || (is_array($val))) { - $this->{$key} = unserialize(serialize($val)); - } - } + throw new Exception( + 'Do not use clone on spreadsheet. Use spreadsheet->copy() instead.' + ); } /** @@ -1562,7 +1574,7 @@ class Spreadsheet * Workbook window is hidden and cannot be shown in the * user interface. * - * @param string $visibility visibility status of the workbook + * @param null|string $visibility visibility status of the workbook */ public function setVisibility($visibility): void { @@ -1596,7 +1608,7 @@ class Spreadsheet */ public function setTabRatio($tabRatio): void { - if ($tabRatio >= 0 || $tabRatio <= 1000) { + if ($tabRatio >= 0 && $tabRatio <= 1000) { $this->tabRatio = (int) $tabRatio; } else { throw new Exception('Tab ratio must be between 0 and 1000.'); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php index 83ac5b0da..68edfaca4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Alignment.php @@ -15,6 +15,27 @@ class Alignment extends Supervisor const HORIZONTAL_JUSTIFY = 'justify'; const HORIZONTAL_FILL = 'fill'; const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only + private const HORIZONTAL_CENTER_CONTINUOUS_LC = 'centercontinuous'; + // Mapping for horizontal alignment + const HORIZONTAL_ALIGNMENT_FOR_XLSX = [ + self::HORIZONTAL_LEFT => self::HORIZONTAL_LEFT, + self::HORIZONTAL_RIGHT => self::HORIZONTAL_RIGHT, + self::HORIZONTAL_CENTER => self::HORIZONTAL_CENTER, + self::HORIZONTAL_CENTER_CONTINUOUS => self::HORIZONTAL_CENTER_CONTINUOUS, + self::HORIZONTAL_JUSTIFY => self::HORIZONTAL_JUSTIFY, + self::HORIZONTAL_FILL => self::HORIZONTAL_FILL, + self::HORIZONTAL_DISTRIBUTED => self::HORIZONTAL_DISTRIBUTED, + ]; + // Mapping for horizontal alignment CSS + const HORIZONTAL_ALIGNMENT_FOR_HTML = [ + self::HORIZONTAL_LEFT => self::HORIZONTAL_LEFT, + self::HORIZONTAL_RIGHT => self::HORIZONTAL_RIGHT, + self::HORIZONTAL_CENTER => self::HORIZONTAL_CENTER, + self::HORIZONTAL_CENTER_CONTINUOUS => self::HORIZONTAL_CENTER, + self::HORIZONTAL_JUSTIFY => self::HORIZONTAL_JUSTIFY, + //self::HORIZONTAL_FILL => self::HORIZONTAL_FILL, // no reasonable equivalent for fill + self::HORIZONTAL_DISTRIBUTED => self::HORIZONTAL_JUSTIFY, + ]; // Vertical alignment styles const VERTICAL_BOTTOM = 'bottom'; @@ -22,6 +43,45 @@ class Alignment extends Supervisor const VERTICAL_CENTER = 'center'; const VERTICAL_JUSTIFY = 'justify'; const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only + // Vertical alignment CSS + private const VERTICAL_BASELINE = 'baseline'; + private const VERTICAL_MIDDLE = 'middle'; + private const VERTICAL_SUB = 'sub'; + private const VERTICAL_SUPER = 'super'; + private const VERTICAL_TEXT_BOTTOM = 'text-bottom'; + private const VERTICAL_TEXT_TOP = 'text-top'; + + // Mapping for vertical alignment + const VERTICAL_ALIGNMENT_FOR_XLSX = [ + self::VERTICAL_BOTTOM => self::VERTICAL_BOTTOM, + self::VERTICAL_TOP => self::VERTICAL_TOP, + self::VERTICAL_CENTER => self::VERTICAL_CENTER, + self::VERTICAL_JUSTIFY => self::VERTICAL_JUSTIFY, + self::VERTICAL_DISTRIBUTED => self::VERTICAL_DISTRIBUTED, + // css settings that arent't in sync with Excel + self::VERTICAL_BASELINE => self::VERTICAL_BOTTOM, + self::VERTICAL_MIDDLE => self::VERTICAL_CENTER, + self::VERTICAL_SUB => self::VERTICAL_BOTTOM, + self::VERTICAL_SUPER => self::VERTICAL_TOP, + self::VERTICAL_TEXT_BOTTOM => self::VERTICAL_BOTTOM, + self::VERTICAL_TEXT_TOP => self::VERTICAL_TOP, + ]; + + // Mapping for vertical alignment for Html + const VERTICAL_ALIGNMENT_FOR_HTML = [ + self::VERTICAL_BOTTOM => self::VERTICAL_BOTTOM, + self::VERTICAL_TOP => self::VERTICAL_TOP, + self::VERTICAL_CENTER => self::VERTICAL_MIDDLE, + self::VERTICAL_JUSTIFY => self::VERTICAL_MIDDLE, + self::VERTICAL_DISTRIBUTED => self::VERTICAL_MIDDLE, + // css settings that arent't in sync with Excel + self::VERTICAL_BASELINE => self::VERTICAL_BASELINE, + self::VERTICAL_MIDDLE => self::VERTICAL_MIDDLE, + self::VERTICAL_SUB => self::VERTICAL_SUB, + self::VERTICAL_SUPER => self::VERTICAL_SUPER, + self::VERTICAL_TEXT_BOTTOM => self::VERTICAL_TEXT_BOTTOM, + self::VERTICAL_TEXT_TOP => self::VERTICAL_TEXT_TOP, + ]; // Read order const READORDER_CONTEXT = 0; @@ -202,8 +262,9 @@ class Alignment extends Supervisor */ public function setHorizontal(string $horizontalAlignment) { - if ($horizontalAlignment == '') { - $horizontalAlignment = self::HORIZONTAL_GENERAL; + $horizontalAlignment = strtolower($horizontalAlignment); + if ($horizontalAlignment === self::HORIZONTAL_CENTER_CONTINUOUS_LC) { + $horizontalAlignment = self::HORIZONTAL_CENTER_CONTINUOUS; } if ($this->isSupervisor) { @@ -239,9 +300,7 @@ class Alignment extends Supervisor */ public function setVertical($verticalAlignment) { - if ($verticalAlignment == '') { - $verticalAlignment = self::VERTICAL_BOTTOM; - } + $verticalAlignment = strtolower($verticalAlignment); if ($this->isSupervisor) { $styleArray = $this->getStyleArray(['vertical' => $verticalAlignment]); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php index 9ab0c98fb..922be803c 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Color.php @@ -387,8 +387,6 @@ class Color extends Supervisor * @param int $colorIndex Index entry point into the colour array * @param bool $background Flag to indicate whether default background or foreground colour * should be returned if the indexed colour doesn't exist - * - * @return Color */ public static function indexedColor($colorIndex, $background = false, ?array $palette = null): self { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php index 54513670e..f7a2eee19 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php @@ -11,10 +11,10 @@ class ConditionalDataBar /** children */ - /** @var ConditionalFormatValueObject */ + /** @var ?ConditionalFormatValueObject */ private $minimumConditionalFormatValueObject; - /** @var ConditionalFormatValueObject */ + /** @var ?ConditionalFormatValueObject */ private $maximumConditionalFormatValueObject; /** @var string */ @@ -22,7 +22,7 @@ class ConditionalDataBar /** */ - /** @var ConditionalFormattingRuleExtension */ + /** @var ?ConditionalFormattingRuleExtension */ private $conditionalFormattingRuleExt; /** @@ -43,10 +43,7 @@ class ConditionalDataBar return $this; } - /** - * @return ConditionalFormatValueObject - */ - public function getMinimumConditionalFormatValueObject() + public function getMinimumConditionalFormatValueObject(): ?ConditionalFormatValueObject { return $this->minimumConditionalFormatValueObject; } @@ -58,10 +55,7 @@ class ConditionalDataBar return $this; } - /** - * @return ConditionalFormatValueObject - */ - public function getMaximumConditionalFormatValueObject() + public function getMaximumConditionalFormatValueObject(): ?ConditionalFormatValueObject { return $this->maximumConditionalFormatValueObject; } @@ -85,10 +79,7 @@ class ConditionalDataBar return $this; } - /** - * @return ConditionalFormattingRuleExtension - */ - public function getConditionalFormattingRuleExt() + public function getConditionalFormattingRuleExt(): ?ConditionalFormattingRuleExtension { return $this->conditionalFormattingRuleExt; } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php index 19d67563e..3d7bc1bce 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Font.php @@ -743,14 +743,14 @@ class Font extends Supervisor private function hashChartColor(?ChartColor $underlineColor): string { - if ($this->underlineColor === null) { + if ($underlineColor === null) { return ''; } return - $this->underlineColor->getValue() - . $this->underlineColor->getType() - . (string) $this->underlineColor->getAlpha(); + $underlineColor->getValue() + . $underlineColor->getType() + . (string) $underlineColor->getAlpha(); } /** diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php index f4d3412bd..07aaff1f7 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php @@ -20,7 +20,8 @@ class PercentageFormatter extends BaseFormatter $format = str_replace('%', '%%', $format); $wholePartSize = strlen((string) floor($value)); - $decimalPartSize = $placeHolders = 0; + $decimalPartSize = 0; + $placeHolders = ''; // Number of decimals if (preg_match('/\.([?0]+)/u', $format, $matches)) { $decimalPartSize = strlen($matches[1]); @@ -29,12 +30,13 @@ class PercentageFormatter extends BaseFormatter $placeHolders = str_repeat(' ', strlen($matches[1]) - $decimalPartSize); } // Number of digits to display before the decimal - if (preg_match('/([#0,]+)\./u', $format, $matches)) { - $wholePartSize = max($wholePartSize, strlen($matches[1])); + if (preg_match('/([#0,]+)\.?/u', $format, $matches)) { + $firstZero = preg_replace('/^[#,]*/', '', $matches[1]); + $wholePartSize = max($wholePartSize, strlen($firstZero)); } - $wholePartSize += $decimalPartSize; - $replacement = "{$wholePartSize}.{$decimalPartSize}"; + $wholePartSize += $decimalPartSize + (int) ($decimalPartSize > 0); + $replacement = "0{$wholePartSize}.{$decimalPartSize}"; $mask = (string) preg_replace('/[#0,]+\.?[?#0,]*/ui', "%{$replacement}f{$placeHolders}", $format); /** @var float */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/CellIterator.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/CellIterator.php index 17286f9c8..94877f667 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/CellIterator.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/CellIterator.php @@ -8,6 +8,7 @@ use PhpOffice\PhpSpreadsheet\Collection\Cells; /** * @template TKey + * * @implements Iterator */ abstract class CellIterator implements Iterator diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php index c23bfc590..4bdc2d4ca 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/PageSetup.php @@ -259,10 +259,11 @@ class PageSetup /** * First page number. * - * @var int + * @var ?int */ private $firstPageNumber; + /** @var string */ private $pageOrder = self::PAGEORDER_DOWN_THEN_OVER; /** @@ -375,7 +376,7 @@ class PageSetup { // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, // but it is apparently still able to handle any scale >= 0, where 0 results in 100 - if (($scale >= 0) || $scale === null) { + if ($scale === null || $scale >= 0) { $this->scale = $scale; if ($update) { $this->fitToPage = false; @@ -845,7 +846,7 @@ class PageSetup /** * Get first page number. * - * @return int + * @return ?int */ public function getFirstPageNumber() { @@ -855,7 +856,7 @@ class PageSetup /** * Set first page number. * - * @param int $value + * @param ?int $value * * @return $this */ diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php index be717053f..8235ccf14 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -32,14 +32,20 @@ use PhpOffice\PhpSpreadsheet\Style\Style; class Worksheet implements IComparable { // Break types - const BREAK_NONE = 0; - const BREAK_ROW = 1; - const BREAK_COLUMN = 2; + public const BREAK_NONE = 0; + public const BREAK_ROW = 1; + public const BREAK_COLUMN = 2; // Sheet state - const SHEETSTATE_VISIBLE = 'visible'; - const SHEETSTATE_HIDDEN = 'hidden'; - const SHEETSTATE_VERYHIDDEN = 'veryHidden'; + public const SHEETSTATE_VISIBLE = 'visible'; + public const SHEETSTATE_HIDDEN = 'hidden'; + public const SHEETSTATE_VERYHIDDEN = 'veryHidden'; + + public const MERGE_CELL_CONTENT_EMPTY = 'empty'; + public const MERGE_CELL_CONTENT_HIDE = 'hide'; + public const MERGE_CELL_CONTENT_MERGE = 'merge'; + + protected const SHEET_NAME_REQUIRES_NO_QUOTES = '/^[_\p{L}][_\p{L}\p{N}]*$/mui'; /** * Maximum 31 characters allowed for sheet title. @@ -917,7 +923,7 @@ class Worksheet implements IComparable $this->parent->getCalculationEngine() ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); if ($updateFormulaCellReferences) { - ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle); + ReferenceHelper::getInstance()->updateNamedFormulae($this->parent, $oldTitle, $newTitle); } } @@ -1265,7 +1271,7 @@ class Worksheet implements IComparable } } elseif ( !preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $coordinate) && - preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/i', $coordinate) + preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/iu', $coordinate) ) { // Named range? $namedRange = $this->validateNamedRange($coordinate, true); @@ -1336,7 +1342,7 @@ class Worksheet implements IComparable * * @return Cell Cell that was created */ - public function createNewCell($coordinate) + public function createNewCell($coordinate): Cell { [$column, $row, $columnString] = Coordinate::indexesFromString($coordinate); $cell = new Cell(null, DataType::TYPE_NULL, $this); @@ -1357,7 +1363,7 @@ class Worksheet implements IComparable if ($rowDimension !== null && $rowDimension->getXfIndex() > 0) { // then there is a row dimension with explicit style, assign it to the cell - $cell->setXfIndex($rowDimension->getXfIndex()); + $cell->setXfIndex(/** @scrutinizer ignore-type */ $rowDimension->getXfIndex()); } elseif ($columnDimension !== null && $columnDimension->getXfIndex() > 0) { // then there is a column dimension, assign it to the cell $cell->setXfIndex($columnDimension->getXfIndex()); @@ -1413,6 +1419,11 @@ class Worksheet implements IComparable return $this->rowDimensions[$row]; } + public function rowDimensionExists(int $row): bool + { + return isset($this->rowDimensions[$row]); + } + /** * Get column dimension at a specific column. * @@ -1751,10 +1762,15 @@ class Worksheet implements IComparable * @param AddressRange|array|string $range A simple string containing a Cell range like 'A1:E10' * or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]), * or an AddressRange. + * @param string $behaviour How the merged cells should behave. + * Possible values are: + * MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells + * MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells + * MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell * * @return $this */ - public function mergeCells($range) + public function mergeCells($range, $behaviour = self::MERGE_CELL_CONTENT_EMPTY) { $range = Functions::trimSheetFromCellReference(Validations::validateCellRange($range)); @@ -1786,18 +1802,22 @@ class Worksheet implements IComparable $this->getCell($upperLeft)->setValueExplicit(null, DataType::TYPE_NULL); } - // Blank out the rest of the cells in the range (if they exist) - if ($numberRows > $numberColumns) { - $this->clearMergeCellsByColumn($firstColumn, $lastColumn, $firstRow, $lastRow, $upperLeft); - } else { - $this->clearMergeCellsByRow($firstColumn, $lastColumnIndex, $firstRow, $lastRow, $upperLeft); + if ($behaviour !== self::MERGE_CELL_CONTENT_HIDE) { + // Blank out the rest of the cells in the range (if they exist) + if ($numberRows > $numberColumns) { + $this->clearMergeCellsByColumn($firstColumn, $lastColumn, $firstRow, $lastRow, $upperLeft, $behaviour); + } else { + $this->clearMergeCellsByRow($firstColumn, $lastColumnIndex, $firstRow, $lastRow, $upperLeft, $behaviour); + } } return $this; } - private function clearMergeCellsByColumn(string $firstColumn, string $lastColumn, int $firstRow, int $lastRow, string $upperLeft): void + private function clearMergeCellsByColumn(string $firstColumn, string $lastColumn, int $firstRow, int $lastRow, string $upperLeft, string $behaviour): void { + $leftCellValue = [$this->getCell($upperLeft)->getFormattedValue()]; + foreach ($this->getColumnIterator($firstColumn, $lastColumn) as $column) { $iterator = $column->getCellIterator($firstRow); $iterator->setIterateOnlyExistingCells(true); @@ -1807,17 +1827,21 @@ class Worksheet implements IComparable if ($row > $lastRow) { break; } - $thisCell = $cell->getColumn() . $row; - if ($upperLeft !== $thisCell) { - $cell->setValueExplicit(null, DataType::TYPE_NULL); - } + $leftCellValue = $this->mergeCellBehaviour($cell, $upperLeft, $behaviour, $leftCellValue); } } } + + $leftCellValue = implode(' ', $leftCellValue); + if ($behaviour === self::MERGE_CELL_CONTENT_MERGE) { + $this->getCell($upperLeft)->setValueExplicit($leftCellValue, DataType::TYPE_STRING); + } } - private function clearMergeCellsByRow(string $firstColumn, int $lastColumnIndex, int $firstRow, int $lastRow, string $upperLeft): void + private function clearMergeCellsByRow(string $firstColumn, int $lastColumnIndex, int $firstRow, int $lastRow, string $upperLeft, string $behaviour): void { + $leftCellValue = [$this->getCell($upperLeft)->getFormattedValue()]; + foreach ($this->getRowIterator($firstRow, $lastRow) as $row) { $iterator = $row->getCellIterator($firstColumn); $iterator->setIterateOnlyExistingCells(true); @@ -1828,13 +1852,31 @@ class Worksheet implements IComparable if ($columnIndex > $lastColumnIndex) { break; } - $thisCell = $column . $cell->getRow(); - if ($upperLeft !== $thisCell) { - $cell->setValueExplicit(null, DataType::TYPE_NULL); - } + $leftCellValue = $this->mergeCellBehaviour($cell, $upperLeft, $behaviour, $leftCellValue); } } } + + $leftCellValue = implode(' ', $leftCellValue); + if ($behaviour === self::MERGE_CELL_CONTENT_MERGE) { + $this->getCell($upperLeft)->setValueExplicit($leftCellValue, DataType::TYPE_STRING); + } + } + + public function mergeCellBehaviour(Cell $cell, string $upperLeft, string $behaviour, array $leftCellValue): array + { + if ($cell->getCoordinate() !== $upperLeft) { + Calculation::getInstance($cell->getWorksheet()->getParent())->flushInstance(); + if ($behaviour === self::MERGE_CELL_CONTENT_MERGE) { + $cellValue = $cell->getFormattedValue(); + if ($cellValue !== '') { + $leftCellValue[] = $cellValue; + } + } + $cell->setValueExplicit(null, DataType::TYPE_NULL); + } + + return $leftCellValue; } /** @@ -1849,17 +1891,22 @@ class Worksheet implements IComparable * @param int $row1 Numeric row coordinate of the first cell * @param int $columnIndex2 Numeric column coordinate of the last cell * @param int $row2 Numeric row coordinate of the last cell + * @param string $behaviour How the merged cells should behave. + * Possible values are: + * MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells + * MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells + * MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell * * @return $this */ - public function mergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2) + public function mergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2, $behaviour = self::MERGE_CELL_CONTENT_EMPTY) { $cellRange = new CellRange( CellAddress::fromColumnAndRow($columnIndex1, $row1), CellAddress::fromColumnAndRow($columnIndex2, $row2) ); - return $this->mergeCells($cellRange); + return $this->mergeCells($cellRange, $behaviour); } /** @@ -2454,10 +2501,8 @@ class Worksheet implements IComparable /** * Show gridlines? - * - * @return bool */ - public function getShowGridlines() + public function getShowGridlines(): bool { return $this->showGridlines; } @@ -2469,7 +2514,7 @@ class Worksheet implements IComparable * * @return $this */ - public function setShowGridlines($showGridLines) + public function setShowGridlines(bool $showGridLines): self { $this->showGridlines = $showGridLines; @@ -2478,10 +2523,8 @@ class Worksheet implements IComparable /** * Print gridlines? - * - * @return bool */ - public function getPrintGridlines() + public function getPrintGridlines(): bool { return $this->printGridlines; } @@ -2493,7 +2536,7 @@ class Worksheet implements IComparable * * @return $this */ - public function setPrintGridlines($printGridLines) + public function setPrintGridlines(bool $printGridLines): self { $this->printGridlines = $printGridLines; @@ -2502,10 +2545,8 @@ class Worksheet implements IComparable /** * Show row and column headers? - * - * @return bool */ - public function getShowRowColHeaders() + public function getShowRowColHeaders(): bool { return $this->showRowColHeaders; } @@ -2517,7 +2558,7 @@ class Worksheet implements IComparable * * @return $this */ - public function setShowRowColHeaders($showRowColHeaders) + public function setShowRowColHeaders(bool $showRowColHeaders): self { $this->showRowColHeaders = $showRowColHeaders; @@ -2526,10 +2567,8 @@ class Worksheet implements IComparable /** * Show summary below? (Row/Column outlining). - * - * @return bool */ - public function getShowSummaryBelow() + public function getShowSummaryBelow(): bool { return $this->showSummaryBelow; } @@ -2541,7 +2580,7 @@ class Worksheet implements IComparable * * @return $this */ - public function setShowSummaryBelow($showSummaryBelow) + public function setShowSummaryBelow(bool $showSummaryBelow): self { $this->showSummaryBelow = $showSummaryBelow; @@ -2550,10 +2589,8 @@ class Worksheet implements IComparable /** * Show summary right? (Row/Column outlining). - * - * @return bool */ - public function getShowSummaryRight() + public function getShowSummaryRight(): bool { return $this->showSummaryRight; } @@ -2565,7 +2602,7 @@ class Worksheet implements IComparable * * @return $this */ - public function setShowSummaryRight($showSummaryRight) + public function setShowSummaryRight(bool $showSummaryRight): self { $this->showSummaryRight = $showSummaryRight; @@ -2589,7 +2626,7 @@ class Worksheet implements IComparable * * @return $this */ - public function setComments(array $comments) + public function setComments(array $comments): self { $this->comments = $comments; @@ -2604,7 +2641,7 @@ class Worksheet implements IComparable * * @return $this */ - public function removeComment($cellCoordinate) + public function removeComment($cellCoordinate): self { $cellAddress = Functions::trimSheetFromCellReference(Validations::validateCellAddress($cellCoordinate)); @@ -2628,10 +2665,8 @@ class Worksheet implements IComparable * * @param array|CellAddress|string $cellCoordinate Coordinate of the cell as a string, eg: 'C5'; * or as an array of [$columnIndex, $row] (e.g. [3, 5]), or a CellAddress object. - * - * @return Comment */ - public function getComment($cellCoordinate) + public function getComment($cellCoordinate): Comment { $cellAddress = Functions::trimSheetFromCellReference(Validations::validateCellAddress($cellCoordinate)); @@ -2664,10 +2699,8 @@ class Worksheet implements IComparable * * @param int $columnIndex Numeric column coordinate of the cell * @param int $row Numeric row coordinate of the cell - * - * @return Comment */ - public function getCommentByColumnAndRow($columnIndex, $row) + public function getCommentByColumnAndRow($columnIndex, $row): Comment { return $this->getComment(Coordinate::stringFromColumnIndex($columnIndex) . $row); } @@ -3046,7 +3079,11 @@ class Worksheet implements IComparable * Extract worksheet title from range. * * Example: extractSheetTitle("testSheet!A1") ==> 'A1' + * Example: extractSheetTitle("testSheet!A1:C3") ==> 'A1:C3' * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> ['testSheet 1', 'A1']; + * Example: extractSheetTitle("'testSheet 1'!A1:C3", true) ==> ['testSheet 1', 'A1:C3']; + * Example: extractSheetTitle("A1", true) ==> ['', 'A1']; + * Example: extractSheetTitle("A1:C3", true) ==> ['', 'A1:C3'] * * @param string $range Range to extract title from * @param bool $returnRange Return range? (see example) @@ -3445,4 +3482,9 @@ class Worksheet implements IComparable { return $this->codeName !== null; } + + public static function nameRequiresQuotes(string $sheetName): bool + { + return preg_match(self::SHEET_NAME_REQUIRES_NO_QUOTES, $sheetName) !== 1; + } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php index da32025a6..0fef0f607 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Html.php @@ -24,6 +24,7 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; +use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Html extends BaseWriter @@ -54,7 +55,7 @@ class Html extends BaseWriter * * @var bool */ - private $embedImages = false; + protected $embedImages = false; /** * Use inline CSS? @@ -126,6 +127,13 @@ class Html extends BaseWriter */ protected $isPdf = false; + /** + * Is the current writer creating mPDF? + * + * @var bool + */ + protected $isMPdf = false; + /** * Generate the Navigation block. * @@ -223,13 +231,6 @@ class Html extends BaseWriter $this->editHtmlCallback = $callback; } - const VALIGN_ARR = [ - Alignment::VERTICAL_BOTTOM => 'bottom', - Alignment::VERTICAL_TOP => 'top', - Alignment::VERTICAL_CENTER => 'middle', - Alignment::VERTICAL_JUSTIFY => 'middle', - ]; - /** * Map VAlign. * @@ -239,17 +240,9 @@ class Html extends BaseWriter */ private function mapVAlign($vAlign) { - return array_key_exists($vAlign, self::VALIGN_ARR) ? self::VALIGN_ARR[$vAlign] : 'baseline'; + return Alignment::VERTICAL_ALIGNMENT_FOR_HTML[$vAlign] ?? ''; } - const HALIGN_ARR = [ - Alignment::HORIZONTAL_LEFT => 'left', - Alignment::HORIZONTAL_RIGHT => 'right', - Alignment::HORIZONTAL_CENTER => 'center', - Alignment::HORIZONTAL_CENTER_CONTINUOUS => 'center', - Alignment::HORIZONTAL_JUSTIFY => 'justify', - ]; - /** * Map HAlign. * @@ -259,7 +252,7 @@ class Html extends BaseWriter */ private function mapHAlign($hAlign) { - return array_key_exists($hAlign, self::HALIGN_ARR) ? self::HALIGN_ARR[$hAlign] : ''; + return Alignment::HORIZONTAL_ALIGNMENT_FOR_HTML[$hAlign] ?? ''; } const BORDER_ARR = [ @@ -280,7 +273,7 @@ class Html extends BaseWriter /** * Map border style. * - * @param int $borderStyle Sheet index + * @param int|string $borderStyle Sheet index * * @return string */ @@ -347,7 +340,7 @@ class Html extends BaseWriter return $this; } - private static function generateMeta($val, $desc) + private static function generateMeta(?string $val, string $desc): string { return $val ? (' ' . PHP_EOL) @@ -391,7 +384,7 @@ class Html extends BaseWriter return $html; } - private function generateSheetPrep() + private function generateSheetPrep(): array { // Ensure that Spans have been calculated? $this->calculateSpans(); @@ -406,7 +399,7 @@ class Html extends BaseWriter return $sheets; } - private function generateSheetStarts($sheet, $rowMin) + private function generateSheetStarts(Worksheet $sheet, int $rowMin): array { // calculate start of , $tbodyStart = $rowMin; @@ -425,7 +418,7 @@ class Html extends BaseWriter return [$theadStart, $theadEnd, $tbodyStart]; } - private function generateSheetTags($row, $theadStart, $theadEnd, $tbodyStart) + private function generateSheetTags(int $row, int $theadStart, int $theadEnd, int $tbodyStart): array { // ? $startTag = ($row == $theadStart) ? (' ' . PHP_EOL) : ''; @@ -544,15 +537,10 @@ class Html extends BaseWriter * Extend Row if chart is placed after nominal end of row. * This code should be exercised by sample: * Chart/32_Chart_read_write_PDF.php. - * However, that test is suppressed due to out-of-date - * Jpgraph code issuing warnings. So, don't measure - * code coverage for this function till that is fixed. * * @param int $row Row to check for charts * * @return array - * - * @codeCoverageIgnore */ private function extendRowsForCharts(Worksheet $worksheet, int $row) { @@ -628,11 +616,12 @@ class Html extends BaseWriter * * @return string */ - public static function winFileToUrl($filename) + public static function winFileToUrl($filename, bool $mpdf = false) { // Windows filename if (substr($filename, 1, 2) === ':\\') { - $filename = 'file:///' . str_replace('\\', '/', $filename); + $protocol = $mpdf ? '' : 'file:///'; + $filename = $protocol . str_replace('\\', '/', $filename); } return $filename; @@ -674,12 +663,12 @@ class Html extends BaseWriter $filename = htmlspecialchars($filename, Settings::htmlEntityFlags()); $html .= PHP_EOL; - $imageData = self::winFileToUrl($filename); + $imageData = self::winFileToUrl($filename, $this->isMPdf); - if (($this->embedImages && !$this->isPdf) || substr($imageData, 0, 6) === 'zip://') { + if ($this->embedImages || substr($imageData, 0, 6) === 'zip://') { $picture = @file_get_contents($filename); if ($picture !== false) { - $imageDetails = getimagesize($filename); + $imageDetails = getimagesize($filename) ?: []; // base64 encode the binary data $base64 = base64_encode($picture); $imageData = 'data:' . $imageDetails['mime'] . ';base64,' . $base64; @@ -694,12 +683,10 @@ class Html extends BaseWriter $imageResource = $drawing->getImageResource(); if ($imageResource) { ob_start(); // Let's start output buffering. - // @phpstan-ignore-next-line imagepng($imageResource); // This will normally output the image, but because of ob_start(), it won't. - $contents = ob_get_contents(); // Instead, output above is saved to $contents + $contents = (string) ob_get_contents(); // Instead, output above is saved to $contents ob_end_clean(); // End the output buffer. - /** @phpstan-ignore-next-line */ $dataUri = 'data:image/png;base64,' . base64_encode($contents); // Because of the nature of tables, width is more important than height. @@ -718,11 +705,6 @@ class Html extends BaseWriter * Generate chart tag in cell. * This code should be exercised by sample: * Chart/32_Chart_read_write_PDF.php. - * However, that test is suppressed due to out-of-date - * Jpgraph code issuing warnings. So, don't measure - * code coverage for this function till that is fixed. - * - * @codeCoverageIgnore */ private function writeChartInCell(Worksheet $worksheet, string $coordinates): string { @@ -740,21 +722,18 @@ class Html extends BaseWriter } $html .= PHP_EOL; - $imageDetails = getimagesize($chartFileName); + $imageDetails = getimagesize($chartFileName) ?: []; $filedesc = $chart->getTitle(); $filedesc = $filedesc ? $filedesc->getCaptionText() : ''; $filedesc = $filedesc ? htmlspecialchars($filedesc, ENT_QUOTES) : 'Embedded chart'; - if ($fp = fopen($chartFileName, 'rb', 0)) { - $picture = fread($fp, filesize($chartFileName)); - fclose($fp); - /** @phpstan-ignore-next-line */ + $picture = file_get_contents($chartFileName); + if ($picture !== false) { $base64 = base64_encode($picture); $imageData = 'data:' . $imageDetails['mime'] . ';base64,' . $base64; $html .= '' . $filedesc . '' . PHP_EOL; - - unlink($chartFileName); } + unlink($chartFileName); } } } @@ -942,8 +921,8 @@ class Html extends BaseWriter // Calculate cell style hashes foreach ($this->spreadsheet->getCellXfCollection() as $index => $style) { - $css['td.style' . $index] = $this->createCSSStyle($style); - $css['th.style' . $index] = $this->createCSSStyle($style); + $css['td.style' . $index . ', th.style' . $index] = $this->createCSSStyle($style); + //$css['th.style' . $index] = $this->createCSSStyle($style); } // Fetch sheets @@ -995,14 +974,25 @@ class Html extends BaseWriter $css = []; // Create CSS - $css['vertical-align'] = $this->mapVAlign($alignment->getVertical()); - $textAlign = $this->mapHAlign($alignment->getHorizontal()); + $verticalAlign = $this->mapVAlign($alignment->getVertical() ?? ''); + if ($verticalAlign) { + $css['vertical-align'] = $verticalAlign; + } + $textAlign = $this->mapHAlign($alignment->getHorizontal() ?? ''); if ($textAlign) { $css['text-align'] = $textAlign; if (in_array($textAlign, ['left', 'right'])) { $css['padding-' . $textAlign] = (string) ((int) $alignment->getIndent() * 9) . 'px'; } } + $rotation = $alignment->getTextRotation(); + if ($rotation !== 0 && $rotation !== Alignment::TEXTROTATION_STACK_PHPSPREADSHEET) { + if ($this->isMPdf) { + $css['text-rotate'] = "$rotation"; + } else { + $css['transform'] = "rotate({$rotation}deg)"; + } + } return $css; } @@ -1064,10 +1054,8 @@ class Html extends BaseWriter * Create CSS style. * * @param Border $border Border - * - * @return string */ - private function createCSSStyleBorder(Border $border) + private function createCSSStyleBorder(Border $border): string { // Create CSS - add !important to non-none border styles for merged cells $borderStyle = $this->mapBorderStyle($border->getBorderStyle()); @@ -1088,9 +1076,11 @@ class Html extends BaseWriter $css = []; // Create CSS - $value = $fill->getFillType() == Fill::FILL_NONE ? - 'white' : '#' . $fill->getStartColor()->getRGB(); - $css['background-color'] = $value; + if ($fill->getFillType() !== Fill::FILL_NONE) { + $value = $fill->getFillType() == Fill::FILL_NONE ? + 'white' : '#' . $fill->getStartColor()->getRGB(); + $css['background-color'] = $value; + } return $css; } @@ -1098,7 +1088,7 @@ class Html extends BaseWriter /** * Generate HTML footer. */ - public function generateHTMLFooter() + public function generateHTMLFooter(): string { // Construct HTML $html = ''; @@ -1108,7 +1098,7 @@ class Html extends BaseWriter return $html; } - private function generateTableTagInline(Worksheet $worksheet, $id) + private function generateTableTagInline(Worksheet $worksheet, string $id): string { $style = isset($this->cssStyles['table']) ? $this->assembleCSS($this->cssStyles['table']) : ''; @@ -1128,7 +1118,7 @@ class Html extends BaseWriter return $html; } - private function generateTableTag(Worksheet $worksheet, $id, &$html, $sheetIndex): void + private function generateTableTag(Worksheet $worksheet, string $id, string &$html, int $sheetIndex): void { if (!$this->useInlineCss) { $gridlines = $worksheet->getShowGridlines() ? ' gridlines' : ''; @@ -1155,9 +1145,9 @@ class Html extends BaseWriter $html = ''; $id = $showid ? "id='sheet$sheetIndex'" : ''; if ($showid) { - $html .= "
\n"; + $html .= "
" . PHP_EOL; } else { - $html .= "
\n"; + $html .= "
" . PHP_EOL; } $this->generateTableTag($worksheet, $id, $html, $sheetIndex); @@ -1181,7 +1171,7 @@ class Html extends BaseWriter /** * Generate table footer. */ - private function generateTableFooter() + private function generateTableFooter(): string { return ' ' . PHP_EOL . '
' . PHP_EOL; } @@ -1227,7 +1217,7 @@ class Html extends BaseWriter return $html; } - private function generateRowCellCss(Worksheet $worksheet, $cellAddress, $row, $columnNumber) + private function generateRowCellCss(Worksheet $worksheet, string $cellAddress, int $row, int $columnNumber): array { $cell = ($cellAddress > '') ? $worksheet->getCellCollection()->get($cellAddress) : ''; $coordinate = Coordinate::stringFromColumnIndex($columnNumber + 1) . ($row + 1); @@ -1253,22 +1243,24 @@ class Html extends BaseWriter return [$cell, $cssClass, $coordinate]; } - private function generateRowCellDataValueRich($cell, &$cellData): void + private function generateRowCellDataValueRich(Cell $cell, string &$cellData): void { // Loop through rich text elements $elements = $cell->getValue()->getRichTextElements(); foreach ($elements as $element) { // Rich text start? if ($element instanceof Run) { - $cellData .= ''; - $cellEnd = ''; - if ($element->getFont()->getSuperscript()) { - $cellData .= ''; - $cellEnd = ''; - } elseif ($element->getFont()->getSubscript()) { - $cellData .= ''; - $cellEnd = ''; + if ($element->getFont() !== null) { + $cellData .= ''; + + if ($element->getFont()->getSuperscript()) { + $cellData .= ''; + $cellEnd = ''; + } elseif ($element->getFont()->getSubscript()) { + $cellData .= ''; + $cellEnd = ''; + } } // Convert UTF8 data to PCDATA @@ -1286,23 +1278,22 @@ class Html extends BaseWriter } } - private function generateRowCellDataValue(Worksheet $worksheet, $cell, &$cellData): void + private function generateRowCellDataValue(Worksheet $worksheet, Cell $cell, string &$cellData): void { if ($cell->getValue() instanceof RichText) { $this->generateRowCellDataValueRich($cell, $cellData); } else { $origData = $this->preCalculateFormulas ? $cell->getCalculatedValue() : $cell->getValue(); $formatCode = $worksheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(); - if ($formatCode !== null) { - $cellData = NumberFormat::toFormattedString( - $origData, - $formatCode, - [$this, 'formatColor'] - ); - } + + $cellData = NumberFormat::toFormattedString( + $origData ?? '', + $formatCode ?? NumberFormat::FORMAT_GENERAL, + [$this, 'formatColor'] + ); if ($cellData === $origData) { - $cellData = htmlspecialchars($cellData ?? '', Settings::htmlEntityFlags()); + $cellData = htmlspecialchars($cellData, Settings::htmlEntityFlags()); } if ($worksheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperscript()) { $cellData = '' . $cellData . ''; @@ -1312,7 +1303,11 @@ class Html extends BaseWriter } } - private function generateRowCellData(Worksheet $worksheet, $cell, &$cssClass, $cellType) + /** + * @param null|Cell|string $cell + * @param array|string $cssClass + */ + private function generateRowCellData(Worksheet $worksheet, $cell, &$cssClass, string $cellType): string { $cellData = ' '; if ($cell instanceof Cell) { @@ -1332,10 +1327,10 @@ class Html extends BaseWriter $cellData = nl2br($cellData); // Extend CSS class? - if (!$this->useInlineCss) { + if (!$this->useInlineCss && is_string($cssClass)) { $cssClass .= ' style' . $cell->getXfIndex(); $cssClass .= ' ' . $cell->getDataType(); - } else { + } elseif (is_array($cssClass)) { if ($cellType == 'th') { if (isset($this->cssStyles['th.style' . $cell->getXfIndex()])) { $cssClass = array_merge($cssClass, $this->cssStyles['th.style' . $cell->getXfIndex()]); @@ -1365,12 +1360,12 @@ class Html extends BaseWriter return $cellData; } - private function generateRowIncludeCharts(Worksheet $worksheet, $coordinate) + private function generateRowIncludeCharts(Worksheet $worksheet, string $coordinate): string { return $this->includeCharts ? $this->writeChartInCell($worksheet, $coordinate) : ''; } - private function generateRowSpans($html, $rowSpan, $colSpan) + private function generateRowSpans(string $html, int $rowSpan, int $colSpan): string { $html .= ($colSpan > 1) ? (' colspan="' . $colSpan . '"') : ''; $html .= ($rowSpan > 1) ? (' rowspan="' . $rowSpan . '"') : ''; @@ -1378,7 +1373,10 @@ class Html extends BaseWriter return $html; } - private function generateRowWriteCell(&$html, Worksheet $worksheet, $coordinate, $cellType, $cellData, $colSpan, $rowSpan, $cssClass, $colNum, $sheetIndex, $row): void + /** + * @param array|string $cssClass + */ + private function generateRowWriteCell(string &$html, Worksheet $worksheet, string $coordinate, string $cellType, string $cellData, int $colSpan, int $rowSpan, $cssClass, int $colNum, int $sheetIndex, int $row): void { // Image? $htmlx = $this->writeImageInCell($worksheet, $coordinate); @@ -1386,7 +1384,7 @@ class Html extends BaseWriter $htmlx .= $this->generateRowIncludeCharts($worksheet, $coordinate); // Column start $html .= ' <' . $cellType; - if (!$this->useInlineCss && !$this->isPdf) { + if (!$this->useInlineCss && !$this->isPdf && is_string($cssClass)) { $html .= ' class="' . $cssClass . '"'; if ($htmlx) { $html .= " style='position: relative;'"; @@ -1396,9 +1394,11 @@ class Html extends BaseWriter // We must explicitly write the width of the element because TCPDF // does not recognize e.g. if ($this->useInlineCss) { - $xcssClass = $cssClass; + $xcssClass = is_array($cssClass) ? $cssClass : []; } else { - $html .= ' class="' . $cssClass . '"'; + if (is_string($cssClass)) { + $html .= ' class="' . $cssClass . '"'; + } $xcssClass = []; } $width = 0; @@ -1409,8 +1409,7 @@ class Html extends BaseWriter $width += $this->columnWidths[$sheetIndex][$i]; } } - $xcssClass['width'] = $width . 'pt'; - + $xcssClass['width'] = (string) $width . 'pt'; // We must also explicitly write the height of the element because TCPDF // does not recognize e.g. if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'])) { @@ -1452,15 +1451,16 @@ class Html extends BaseWriter // Sheet index $sheetIndex = $worksheet->getParent()->getIndex($worksheet); $html = $this->generateRowStart($worksheet, $sheetIndex, $row); + $generateDiv = $this->isMPdf && $worksheet->getRowDimension($row + 1)->getVisible() === false; + if ($generateDiv) { + $html .= '
' . PHP_EOL; + } // Write cells $colNum = 0; foreach ($values as $cellAddress) { [$cell, $cssClass, $coordinate] = $this->generateRowCellCss($worksheet, $cellAddress, $row, $colNum); - $colSpan = 1; - $rowSpan = 1; - // Cell Data $cellData = $this->generateRowCellData($worksheet, $cell, $cssClass, $cellType); @@ -1474,8 +1474,8 @@ class Html extends BaseWriter && $this->isSpannedCell[$worksheet->getParent()->getIndex($worksheet)][$row + 1][$colNum]); // Colspan and Rowspan - $colspan = 1; - $rowspan = 1; + $colSpan = 1; + $rowSpan = 1; if (isset($this->isBaseCell[$worksheet->getParent()->getIndex($worksheet)][$row + 1][$colNum])) { $spans = $this->isBaseCell[$worksheet->getParent()->getIndex($worksheet)][$row + 1][$colNum]; $rowSpan = $spans['rowspan']; @@ -1499,6 +1499,9 @@ class Html extends BaseWriter } // Write row end + if ($generateDiv) { + $html .= '
' . PHP_EOL; + } $html .= ' ' . PHP_EOL; // Return @@ -1722,7 +1725,7 @@ class Html extends BaseWriter $this->spansAreCalculated = true; } - private function calculateSpansOmitRows($sheet, $sheetIndex, $candidateSpannedRow): void + private function calculateSpansOmitRows(Worksheet $sheet, int $sheetIndex, array $candidateSpannedRow): void { // Identify which rows should be omitted in HTML. These are the rows where all the cells // participate in a merge and the where base cells are somewhere above. @@ -1785,7 +1788,8 @@ class Html extends BaseWriter public function getOrientation(): ?string { - return null; + // Expect Pdf classes to override this method. + return $this->isPdf ? PageSetup::ORIENTATION_PORTRAIT : null; } /** @@ -1824,31 +1828,31 @@ class Html extends BaseWriter $bottom = StringHelper::FormatNumber($worksheet->getPageMargins()->getBottom()) . 'in; '; $htmlPage .= 'margin-bottom: ' . $bottom; $orientation = $this->getOrientation() ?? $worksheet->getPageSetup()->getOrientation(); - if ($orientation === \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE) { + if ($orientation === PageSetup::ORIENTATION_LANDSCAPE) { $htmlPage .= 'size: landscape; '; - } elseif ($orientation === \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_PORTRAIT) { + } elseif ($orientation === PageSetup::ORIENTATION_PORTRAIT) { $htmlPage .= 'size: portrait; '; } - $htmlPage .= "}\n"; + $htmlPage .= '}' . PHP_EOL; ++$sheetId; } - $htmlPage .= <<div {margin-top: 5px;} - body>div:first-child {margin-top: 0;} - .scrpgbrk {margin-top: 1px;} -} -@media print { - .gridlinesp td {border: 1px solid black;} - .gridlinesp th {border: 1px solid black;} - .navigation {display: none;} -} - -EOF; + $htmlPage .= implode(PHP_EOL, [ + '.navigation {page-break-after: always;}', + '.scrpgbrk, div + div {page-break-before: always;}', + '@media screen {', + ' .gridlines td {border: 1px solid black;}', + ' .gridlines th {border: 1px solid black;}', + ' body>div {margin-top: 5px;}', + ' body>div:first-child {margin-top: 0;}', + ' .scrpgbrk {margin-top: 1px;}', + '}', + '@media print {', + ' .gridlinesp td {border: 1px solid black;}', + ' .gridlinesp th {border: 1px solid black;}', + ' .navigation {display: none;}', + '}', + '', + ]); $htmlPage .= $generateSurroundingHTML ? ('' . PHP_EOL) : ''; return $htmlPage; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/IWriter.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/IWriter.php index b0a627260..d8bf1f0c1 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/IWriter.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/IWriter.php @@ -62,6 +62,8 @@ interface IWriter * Save PhpSpreadsheet to file. * * @param resource|string $filename Name of the file to save + * + * @throws Exception */ public function save($filename, int $flags = 0): void; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php index fc96f9049..690b0c54a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php @@ -7,6 +7,13 @@ use PhpOffice\PhpSpreadsheet\Writer\Pdf; class Dompdf extends Pdf { + /** + * embed images, or link to images. + * + * @var bool + */ + protected $embedImages = true; + /** * Gets the implementation of external PDF library that should be used. * @@ -26,15 +33,15 @@ class Dompdf extends Pdf { $fileHandle = parent::prepareForSave($filename); - // Default PDF paper size - $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) - // Check for paper size and page orientation $setup = $this->spreadsheet->getSheet($this->getSheetIndex() ?? 0)->getPageSetup(); $orientation = $this->getOrientation() ?? $setup->getOrientation(); $orientation = ($orientation === PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->getPaperSize() ?? $setup->getPaperSize(); $paperSize = self::$paperSizes[$printPaperSize] ?? PageSetup::getPaperSizeDefault(); + if (is_array($paperSize) && count($paperSize) === 2) { + $paperSize = [0.0, 0.0, $paperSize[0], $paperSize[1]]; + } $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php index 281e1a4f9..d0ce9ed45 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php @@ -8,6 +8,9 @@ use PhpOffice\PhpSpreadsheet\Writer\Pdf; class Mpdf extends Pdf { + /** @var bool */ + protected $isMPdf = true; + /** * Gets the implementation of external PDF library that should be used. * diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php index d29d47648..aefc6b56d 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php @@ -77,7 +77,7 @@ class Tcpdf extends Pdf $pdf->SetCreator($this->spreadsheet->getProperties()->getCreator()); // Write to file - fwrite($fileHandle, $pdf->output($filename, 'S')); + fwrite($fileHandle, $pdf->output('', 'S')); parent::restoreStateAfterSave(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php index eadf0083e..69457357b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls.php @@ -732,7 +732,6 @@ class Xls extends BaseWriter } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); - // @phpstan-ignore-next-line ++$dataProp['data']['length']; // Complete the string with null string for being a %4 $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (4 - $dataProp['data']['length'] % 4)); @@ -750,7 +749,6 @@ class Xls extends BaseWriter } else { $dataSection_Content .= $dataProp['data']['data']; - // @phpstan-ignore-next-line $dataSection_Content_Offset += 4 + $dataProp['data']['length']; } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php index 2f75f9082..ca407d2a0 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Parser.php @@ -78,7 +78,7 @@ class Parser /** * The parse tree to be generated. * - * @var string + * @var array|string */ public $parseTree; @@ -531,7 +531,7 @@ class Parser { return($this->convertFunction($token, $this->_func_args)); }*/ - // if it's an argument, ignore the token (the argument remains) + // if it's an argument, ignore the token (the argument remains) } elseif ($token == 'arg') { return ''; } @@ -1445,6 +1445,9 @@ class Parser if (empty($tree)) { // If it's the first call use parseTree $tree = $this->parseTree; } + if (!is_array($tree) || !isset($tree['left'], $tree['right'], $tree['value'])) { + throw new WriterException('Unexpected non-array'); + } if (is_array($tree['left'])) { $converted_tree = $this->toReversePolish($tree['left']); @@ -1475,7 +1478,7 @@ class Parser $left_tree = ''; } - // add it's left subtree and return. + // add its left subtree and return. return $left_tree . $this->convertFunction($tree['value'], $tree['right']); } $converted_tree = $this->convert($tree['value']); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 378655183..78fda5174 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -465,7 +465,7 @@ class Worksheet extends BIFFwriter switch ($calctype) { case 'integer': case 'double': - $this->writeNumber($row, $column, $calculatedValue, $xfIndex); + $this->writeNumber($row, $column, (float) $calculatedValue, $xfIndex); break; case 'string': @@ -473,7 +473,7 @@ class Worksheet extends BIFFwriter break; case 'boolean': - $this->writeBoolErr($row, $column, $calculatedValue, 0, $xfIndex); + $this->writeBoolErr($row, $column, (int) $calculatedValue, 0, $xfIndex); break; default: @@ -2405,10 +2405,12 @@ class Worksheet extends BIFFwriter for ($i = 0; $i < $width; ++$i) { /** @phpstan-ignore-next-line */ $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); - foreach (['red', 'green', 'blue'] as $key) { - $color[$key] = $color[$key] + (int) round((255 - $color[$key]) * $color['alpha'] / 127); + if ($color !== false) { + foreach (['red', 'green', 'blue'] as $key) { + $color[$key] = $color[$key] + (int) round((255 - $color[$key]) * $color['alpha'] / 127); + } + $data .= chr($color['blue']) . chr($color['green']) . chr($color['red']); } - $data .= chr($color['blue']) . chr($color['green']) . chr($color['red']); } if (3 * $width % 4) { $data .= str_repeat("\x00", 4 - 3 * $width % 4); @@ -2836,7 +2838,7 @@ class Worksheet extends BIFFwriter $operatorType = 0x01; break; - // not OPERATOR_NOTBETWEEN 0x02 + // not OPERATOR_NOTBETWEEN 0x02 } } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php index 5aca51174..c9446e707 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php @@ -349,12 +349,15 @@ class Xlsx extends BaseWriter //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) if ($this->spreadSheet->hasRibbon()) { $tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target'); + $tmpRibbonTarget = is_string($tmpRibbonTarget) ? $tmpRibbonTarget : ''; $zipContent[$tmpRibbonTarget] = $this->spreadSheet->getRibbonXMLData('data'); if ($this->spreadSheet->hasRibbonBinObjects()) { $tmpRootPath = dirname($tmpRibbonTarget) . '/'; $ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data'); //the files to write - foreach ($ribbonBinObjects as $aPath => $aContent) { - $zipContent[$tmpRootPath . $aPath] = $aContent; + if (is_array($ribbonBinObjects)) { + foreach ($ribbonBinObjects as $aPath => $aContent) { + $zipContent[$tmpRootPath . $aPath] = $aContent; + } } //the rels for files $zipContent[$tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels'] = $this->getWriterPartRelsRibbon()->writeRibbonRelationships($this->spreadSheet); @@ -684,6 +687,7 @@ class Xlsx extends BaseWriter return $this; } + /** @var array */ private $pathNames = []; private function addZipFile(string $path, string $content): void diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php index 356b44e97..3b64bd8e9 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -11,6 +11,7 @@ use PhpOffice\PhpSpreadsheet\Chart\Legend; use PhpOffice\PhpSpreadsheet\Chart\PlotArea; use PhpOffice\PhpSpreadsheet\Chart\Properties; use PhpOffice\PhpSpreadsheet\Chart\Title; +use PhpOffice\PhpSpreadsheet\Chart\TrendLine; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException; @@ -58,7 +59,7 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', 'en-GB'); $objWriter->endElement(); $objWriter->startElement('c:roundedCorners'); - $objWriter->writeAttribute('val', '0'); + $objWriter->writeAttribute('val', $chart->getRoundedCorners() ? '1' : '0'); $objWriter->endElement(); $this->writeAlternateContent($objWriter); @@ -68,34 +69,26 @@ class Chart extends WriterPart $this->writeTitle($objWriter, $chart->getTitle()); $objWriter->startElement('c:autoTitleDeleted'); - $objWriter->writeAttribute('val', '0'); + $objWriter->writeAttribute('val', (string) (int) $chart->getAutoTitleDeleted()); $objWriter->endElement(); $objWriter->startElement('c:view3D'); - $rotX = $chart->getRotX(); - if (is_int($rotX)) { - $objWriter->startElement('c:rotX'); - $objWriter->writeAttribute('val', "$rotX"); - $objWriter->endElement(); - } - $rotY = $chart->getRotY(); - if (is_int($rotY)) { - $objWriter->startElement('c:rotY'); - $objWriter->writeAttribute('val', "$rotY"); - $objWriter->endElement(); - } - $rAngAx = $chart->getRAngAx(); - if (is_int($rAngAx)) { - $objWriter->startElement('c:rAngAx'); - $objWriter->writeAttribute('val', "$rAngAx"); - $objWriter->endElement(); - } - $perspective = $chart->getPerspective(); - if (is_int($perspective)) { - $objWriter->startElement('c:perspective'); - $objWriter->writeAttribute('val', "$perspective"); - $objWriter->endElement(); + $surface2D = false; + $plotArea = $chart->getPlotArea(); + if ($plotArea !== null) { + $seriesArray = $plotArea->getPlotGroup(); + foreach ($seriesArray as $series) { + if ($series->getPlotType() === DataSeries::TYPE_SURFACECHART) { + $surface2D = true; + + break; + } + } } + $this->writeView3D($objWriter, $chart->getRotX(), 'c:rotX', $surface2D, 90); + $this->writeView3D($objWriter, $chart->getRotY(), 'c:rotY', $surface2D); + $this->writeView3D($objWriter, $chart->getRAngAx(), 'c:rAngAx', $surface2D); + $this->writeView3D($objWriter, $chart->getPerspective(), 'c:perspective', $surface2D); $objWriter->endElement(); // view3D $this->writePlotArea($objWriter, $chart->getPlotArea(), $chart->getXAxisLabel(), $chart->getYAxisLabel(), $chart->getChartAxisX(), $chart->getChartAxisY()); @@ -114,16 +107,34 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', '0'); $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); // c:chart + if ($chart->getNoFill()) { + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); // a:noFill + $objWriter->endElement(); // c:spPr + } $this->writePrintSettings($objWriter); - $objWriter->endElement(); + $objWriter->endElement(); // c:chartSpace // Return return $objWriter->getData(); } + private function writeView3D(XMLWriter $objWriter, ?int $value, string $tag, bool $surface2D, int $default = 0): void + { + if ($value === null && $surface2D) { + $value = $default; + } + if ($value !== null) { + $objWriter->startElement($tag); + $objWriter->writeAttribute('val', "$value"); + $objWriter->endElement(); + } + } + /** * Write Chart Title. */ @@ -222,8 +233,6 @@ class Chart extends WriterPart if ($plotArea === null) { return; } - $majorGridlines = ($yAxis === null) ? null : $yAxis->getMajorGridlines(); - $minorGridlines = ($yAxis === null) ? null : $yAxis->getMinorGridlines(); $id1 = $id2 = $id3 = '0'; $this->seriesIndex = 0; @@ -356,8 +365,35 @@ class Chart extends WriterPart $this->writeSerAxis($objWriter, $id2, $id3); } } + $stops = $plotArea->getGradientFillStops(); + if ($plotArea->getNoFill() || !empty($stops)) { + $objWriter->startElement('c:spPr'); + if ($plotArea->getNoFill()) { + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); // a:noFill + } + if (!empty($stops)) { + $objWriter->startElement('a:gradFill'); + $objWriter->startElement('a:gsLst'); + foreach ($stops as $stop) { + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', (string) (Properties::PERCENTAGE_MULTIPLIER * (float) $stop[0])); + $this->writeColor($objWriter, $stop[1], false); + $objWriter->endElement(); // a:gs + } + $objWriter->endElement(); // a:gsLst + $angle = $plotArea->getGradientFillAngle(); + if ($angle !== null) { + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', Properties::angleToXml($angle)); + $objWriter->endElement(); // a:lin + } + $objWriter->endElement(); // a:gradFill + } + $objWriter->endElement(); // c:spPr + } - $objWriter->endElement(); + $objWriter->endElement(); // c:plotArea } private function writeDataLabelsBool(XMLWriter $objWriter, string $name, ?bool $value): void @@ -420,6 +456,17 @@ class Chart extends WriterPart $objWriter->endElement(); // c:txPr } + if ($chartLayout->getNumFmtCode() !== '') { + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', $chartLayout->getnumFmtCode()); + $objWriter->writeAttribute('sourceLinked', (string) (int) $chartLayout->getnumFmtLinked()); + $objWriter->endElement(); // c:numFmt + } + if ($chartLayout->getDLblPos() !== '') { + $objWriter->startElement('c:dLblPos'); + $objWriter->writeAttribute('val', $chartLayout->getDLblPos()); + $objWriter->endElement(); // c:dLblPos + } $this->writeDataLabelsBool($objWriter, 'showLegendKey', $chartLayout->getShowLegendKey()); $this->writeDataLabelsBool($objWriter, 'showVal', $chartLayout->getShowVal()); $this->writeDataLabelsBool($objWriter, 'showCatName', $chartLayout->getShowCatName()); @@ -441,13 +488,14 @@ class Chart extends WriterPart private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis): void { // N.B. writeCategoryAxis may be invoked with the last parameter($yAxis) using $xAxis for ScatterChart, etc - // In that case, xAxis is NOT a category. - if ($yAxis->getAxisType() !== '') { - $objWriter->startElement('c:' . $yAxis->getAxisType()); + // In that case, xAxis may contain values like the yAxis, or it may be a date axis (LINECHART). + $axisType = $yAxis->getAxisType(); + if ($axisType !== '') { + $objWriter->startElement("c:$axisType"); } elseif ($yAxis->getAxisIsNumericFormat()) { - $objWriter->startElement('c:valAx'); + $objWriter->startElement('c:' . Axis::AXIS_TYPE_VALUE); } else { - $objWriter->startElement('c:catAx'); + $objWriter->startElement('c:' . Axis::AXIS_TYPE_CATEGORY); } $majorGridlines = $yAxis->getMajorGridlines(); $minorGridlines = $yAxis->getMinorGridlines(); @@ -477,7 +525,7 @@ class Chart extends WriterPart $objWriter->endElement(); // c:scaling $objWriter->startElement('c:delete'); - $objWriter->writeAttribute('val', '0'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('hidden') ?? '0'); $objWriter->endElement(); $objWriter->startElement('c:axPos'); @@ -558,6 +606,23 @@ class Chart extends WriterPart $objWriter->endElement(); } + $textRotation = $yAxis->getAxisOptionsProperty('textRotation'); + if (is_numeric($textRotation)) { + $objWriter->startElement('c:txPr'); + $objWriter->startElement('a:bodyPr'); + $objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation)); + $objWriter->endElement(); // a:bodyPr + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); // a:lstStyle + $objWriter->startElement('a:p'); + $objWriter->startElement('a:pPr'); + $objWriter->startElement('a:defRPr'); + $objWriter->endElement(); // a:defRPr + $objWriter->endElement(); // a:pPr + $objWriter->endElement(); // a:p + $objWriter->endElement(); // c:txPr + } + $objWriter->startElement('c:spPr'); $this->writeColor($objWriter, $yAxis->getFillColorObject()); $this->writeEffects($objWriter, $yAxis); @@ -588,7 +653,8 @@ class Chart extends WriterPart } $objWriter->startElement('c:auto'); - $objWriter->writeAttribute('val', '1'); + // LineChart with dateAx wants '0' + $objWriter->writeAttribute('val', ($axisType === Axis::AXIS_TYPE_DATE) ? '0' : '1'); $objWriter->endElement(); $objWriter->startElement('c:lblAlgn'); @@ -599,6 +665,30 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', '100'); $objWriter->endElement(); + if ($axisType === Axis::AXIS_TYPE_DATE) { + $property = 'baseTimeUnit'; + $propertyVal = $yAxis->getAxisOptionsProperty($property); + if (!empty($propertyVal)) { + $objWriter->startElement("c:$property"); + $objWriter->writeAttribute('val', $propertyVal); + $objWriter->endElement(); + } + $property = 'majorTimeUnit'; + $propertyVal = $yAxis->getAxisOptionsProperty($property); + if (!empty($propertyVal)) { + $objWriter->startElement("c:$property"); + $objWriter->writeAttribute('val', $propertyVal); + $objWriter->endElement(); + } + $property = 'minorTimeUnit'; + $propertyVal = $yAxis->getAxisOptionsProperty($property); + if (!empty($propertyVal)) { + $objWriter->startElement("c:$property"); + $objWriter->writeAttribute('val', $propertyVal); + $objWriter->endElement(); + } + } + if ($isMultiLevelSeries) { $objWriter->startElement('c:noMultiLvlLbl'); $objWriter->writeAttribute('val', '0'); @@ -617,7 +707,7 @@ class Chart extends WriterPart */ private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis): void { - $objWriter->startElement('c:valAx'); + $objWriter->startElement('c:' . Axis::AXIS_TYPE_VALUE); $majorGridlines = $xAxis->getMajorGridlines(); $minorGridlines = $xAxis->getMinorGridlines(); @@ -650,7 +740,7 @@ class Chart extends WriterPart $objWriter->endElement(); // c:scaling $objWriter->startElement('c:delete'); - $objWriter->writeAttribute('val', '0'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('hidden') ?? '0'); $objWriter->endElement(); $objWriter->startElement('c:axPos'); @@ -733,6 +823,23 @@ class Chart extends WriterPart $objWriter->endElement(); } + $textRotation = $xAxis->getAxisOptionsProperty('textRotation'); + if (is_numeric($textRotation)) { + $objWriter->startElement('c:txPr'); + $objWriter->startElement('a:bodyPr'); + $objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation)); + $objWriter->endElement(); // a:bodyPr + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); // a:lstStyle + $objWriter->startElement('a:p'); + $objWriter->startElement('a:pPr'); + $objWriter->startElement('a:defRPr'); + $objWriter->endElement(); // a:defRPr + $objWriter->endElement(); // a:pPr + $objWriter->endElement(); // a:p + $objWriter->endElement(); // c:txPr + } + $objWriter->startElement('c:spPr'); $this->writeColor($objWriter, $xAxis->getFillColorObject()); $this->writeLineStyles($objWriter, $xAxis); @@ -875,10 +982,6 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', "$val"); $objWriter->endElement(); // c:idx - $objWriter->startElement('c:bubble3D'); - $objWriter->writeAttribute('val', '0'); - $objWriter->endElement(); // c:bubble3D - $objWriter->startElement('c:spPr'); $this->writeColor($objWriter, $fillColor); $objWriter->endElement(); // c:spPr @@ -906,8 +1009,8 @@ class Chart extends WriterPart $objWriter->endElement(); } - if ($plotGroup->getPlotGrouping() !== null) { - $plotGroupingType = $plotGroup->getPlotGrouping(); + $plotGroupingType = $plotGroup->getPlotGrouping(); + if ($plotGroupingType !== null && $groupType !== DataSeries::TYPE_SURFACECHART && $groupType !== DataSeries::TYPE_SURFACECHART_3D) { $objWriter->startElement('c:grouping'); $objWriter->writeAttribute('val', $plotGroupingType); $objWriter->endElement(); @@ -1000,7 +1103,7 @@ class Chart extends WriterPart $objWriter->endElement(); // a:ln } } - $nofill = $groupType == DataSeries::TYPE_STOCKCHART || ($groupType === DataSeries::TYPE_SCATTERCHART && !$plotSeriesValues->getScatterLines()); + $nofill = $groupType === DataSeries::TYPE_STOCKCHART || (($groupType === DataSeries::TYPE_SCATTERCHART || $groupType === DataSeries::TYPE_LINECHART) && !$plotSeriesValues->getScatterLines()); if ($callLineStyles) { $this->writeLineStyles($objWriter, $plotSeriesValues, $nofill); $this->writeEffects($objWriter, $plotSeriesValues); @@ -1045,6 +1148,88 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', '0'); $objWriter->endElement(); } + // Trendlines + if ($plotSeriesValues !== false) { + foreach ($plotSeriesValues->getTrendLines() as $trendLine) { + $trendLineType = $trendLine->getTrendLineType(); + $order = $trendLine->getOrder(); + $period = $trendLine->getPeriod(); + $dispRSqr = $trendLine->getDispRSqr(); + $dispEq = $trendLine->getDispEq(); + $forward = $trendLine->getForward(); + $backward = $trendLine->getBackward(); + $intercept = $trendLine->getIntercept(); + $name = $trendLine->getName(); + $trendLineColor = $trendLine->getLineColor(); // ChartColor + + $objWriter->startElement('c:trendline'); // N.B. lowercase 'ell' + if ($name !== '') { + $objWriter->startElement('c:name'); + $objWriter->writeRawData($name); + $objWriter->endElement(); // c:name + } + $objWriter->startElement('c:spPr'); + + if (!$trendLineColor->isUsable()) { + // use dataSeriesValues line color as a backup if $trendLineColor is null + $dsvLineColor = $plotSeriesValues->getLineColor(); + if ($dsvLineColor->isUsable()) { + $trendLine + ->getLineColor() + ->setColorProperties($dsvLineColor->getValue(), $dsvLineColor->getAlpha(), $dsvLineColor->getType()); + } + } // otherwise, hope Excel does the right thing + + $this->writeLineStyles($objWriter, $trendLine, false); // suppress noFill + + $objWriter->endElement(); // spPr + + $objWriter->startElement('c:trendlineType'); // N.B lowercase 'ell' + $objWriter->writeAttribute('val', $trendLineType); + $objWriter->endElement(); // trendlineType + if ($backward !== 0.0) { + $objWriter->startElement('c:backward'); + $objWriter->writeAttribute('val', "$backward"); + $objWriter->endElement(); // c:backward + } + if ($forward !== 0.0) { + $objWriter->startElement('c:forward'); + $objWriter->writeAttribute('val', "$forward"); + $objWriter->endElement(); // c:forward + } + if ($intercept !== 0.0) { + $objWriter->startElement('c:intercept'); + $objWriter->writeAttribute('val', "$intercept"); + $objWriter->endElement(); // c:intercept + } + if ($trendLineType == TrendLine::TRENDLINE_POLYNOMIAL) { + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $order); + $objWriter->endElement(); // order + } + if ($trendLineType == TrendLine::TRENDLINE_MOVING_AVG) { + $objWriter->startElement('c:period'); + $objWriter->writeAttribute('val', $period); + $objWriter->endElement(); // period + } + $objWriter->startElement('c:dispRSqr'); + $objWriter->writeAttribute('val', $dispRSqr ? '1' : '0'); + $objWriter->endElement(); + $objWriter->startElement('c:dispEq'); + $objWriter->writeAttribute('val', $dispEq ? '1' : '0'); + $objWriter->endElement(); + if ($groupType === DataSeries::TYPE_SCATTERCHART || $groupType === DataSeries::TYPE_LINECHART) { + $objWriter->startElement('c:trendlineLbl'); + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', 'General'); + $objWriter->writeAttribute('sourceLinked', '0'); + $objWriter->endElement(); // numFmt + $objWriter->endElement(); // trendlineLbl + } + + $objWriter->endElement(); // trendline + } + } // Category Labels $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesIdx); @@ -1052,13 +1237,11 @@ class Chart extends WriterPart $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) { - if ($plotGroup->getPlotStyle() !== null) { - $plotStyle = $plotGroup->getPlotStyle(); - if ($plotStyle) { - $objWriter->startElement('c:explosion'); - $objWriter->writeAttribute('val', '25'); - $objWriter->endElement(); - } + $plotStyle = $plotGroup->getPlotStyle(); + if (is_numeric($plotStyle)) { + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', $plotStyle); + $objWriter->endElement(); } } @@ -1569,7 +1752,18 @@ class Chart extends WriterPart if (is_numeric($alpha)) { $objWriter->startElement('a:alpha'); $objWriter->writeAttribute('val', ChartColor::alphaToXml((int) $alpha)); - $objWriter->endElement(); + $objWriter->endElement(); // a:alpha + } + $brightness = $chartColor->getBrightness(); + if (is_numeric($brightness)) { + $brightness = (int) $brightness; + $lumOff = 100 - $brightness; + $objWriter->startElement('a:lumMod'); + $objWriter->writeAttribute('val', ChartColor::alphaToXml($brightness)); + $objWriter->endElement(); // a:lumMod + $objWriter->startElement('a:lumOff'); + $objWriter->writeAttribute('val', ChartColor::alphaToXml($lumOff)); + $objWriter->endElement(); // a:lumOff } $objWriter->endElement(); //a:srgbClr/schemeClr/prstClr if ($solidFill) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php index ea0f1faa6..5045e8f38 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Comments.php @@ -165,7 +165,7 @@ class Comments extends WriterPart // Metadata [$column, $row] = Coordinate::indexesFromString($cellReference); $id = 1024 + $column + $row; - $id = substr($id, 0, 4); + $id = substr("$id", 0, 4); // v:shape $objWriter->startElement('v:shape'); @@ -223,10 +223,10 @@ class Comments extends WriterPart $objWriter->writeElement('x:AutoFill', 'False'); // x:Row - $objWriter->writeElement('x:Row', ($row - 1)); + $objWriter->writeElement('x:Row', (string) ($row - 1)); // x:Column - $objWriter->writeElement('x:Column', ($column - 1)); + $objWriter->writeElement('x:Column', (string) ($column - 1)); $objWriter->endElement(); diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php index b8285fcbe..b3338c07b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php @@ -118,7 +118,7 @@ class DefinedNames $range[1] = Coordinate::absoluteCoordinate($range[1]); $range = implode(':', $range); - $this->objWriter->writeRawData('\'' . str_replace("'", "''", $worksheet->getTitle() ?? '') . '\'!' . $range); + $this->objWriter->writeRawData('\'' . str_replace("'", "''", $worksheet->getTitle()) . '\'!' . $range); $this->objWriter->endElement(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php index 43ce442fe..cb8758c2b 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php @@ -56,7 +56,7 @@ class DocProps extends WriterPart // Variant $objWriter->startElement('vt:variant'); - $objWriter->writeElement('vt:i4', $spreadsheet->getSheetCount()); + $objWriter->writeElement('vt:i4', (string) $spreadsheet->getSheetCount()); $objWriter->endElement(); $objWriter->endElement(); @@ -68,7 +68,7 @@ class DocProps extends WriterPart // Vector $objWriter->startElement('vt:vector'); - $objWriter->writeAttribute('size', $spreadsheet->getSheetCount()); + $objWriter->writeAttribute('size', (string) $spreadsheet->getSheetCount()); $objWriter->writeAttribute('baseType', 'lpstr'); $sheetCount = $spreadsheet->getSheetCount(); @@ -207,7 +207,7 @@ class DocProps extends WriterPart $objWriter->startElement('property'); $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); - $objWriter->writeAttribute('pid', $key + 2); + $objWriter->writeAttribute('pid', (string) ($key + 2)); $objWriter->writeAttribute('name', $customProperty); switch ($propertyType) { diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index 238fb5bf6..99fa2d34a 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -67,12 +67,13 @@ class Rels extends WriterPart 'xl/workbook.xml' ); // a custom UI in workbook ? + $target = $spreadsheet->getRibbonXMLData('target'); if ($spreadsheet->hasRibbon()) { $this->writeRelationShip( $objWriter, 5, 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', - $spreadsheet->getRibbonXMLData('target') + is_string($target) ? $target : '' ); } @@ -284,7 +285,7 @@ class Rels extends WriterPart return $objWriter->getData(); } - private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, XMLWriter $objWriter, $relationship, $type): void + private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet, XMLWriter $objWriter, string $relationship, string $type): void { $unparsedLoadedData = $worksheet->getParent()->getUnparsedLoadedData(); if (!isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()][$relationship])) { @@ -448,7 +449,7 @@ class Rels extends WriterPart /** * Write Override content type. * - * @param int $id Relationship ID. rId will be prepended! + * @param int|string $id Relationship ID. rId will be prepended! * @param string $type Relationship type * @param string $target Relationship target * @param string $targetMode Relationship target mode diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php index 8b293bc19..078f940ac 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php @@ -66,7 +66,7 @@ class StringTable extends WriterPart /** * Write string table to XML format. * - * @param string[] $stringTable + * @param (string|RichText)[] $stringTable * * @return string XML Output */ @@ -86,13 +86,13 @@ class StringTable extends WriterPart // String table $objWriter->startElement('sst'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - $objWriter->writeAttribute('uniqueCount', count($stringTable)); + $objWriter->writeAttribute('uniqueCount', (string) count($stringTable)); // Loop through string table foreach ($stringTable as $textElement) { $objWriter->startElement('si'); - if (!$textElement instanceof RichText) { + if (!($textElement instanceof RichText)) { $textToWrite = StringHelper::controlCharacterPHP2OOXML($textElement); $objWriter->startElement('t'); if ($textToWrite !== trim($textToWrite)) { @@ -100,7 +100,7 @@ class StringTable extends WriterPart } $objWriter->writeRawData($textToWrite); $objWriter->endElement(); - } elseif ($textElement instanceof RichText) { + } else { $this->writeRichText($objWriter, $textElement); } @@ -130,14 +130,16 @@ class StringTable extends WriterPart $objWriter->startElement($prefix . 'r'); // rPr - if ($element instanceof Run) { + if ($element instanceof Run && $element->getFont() !== null) { // rPr $objWriter->startElement($prefix . 'rPr'); // rFont - $objWriter->startElement($prefix . 'rFont'); - $objWriter->writeAttribute('val', $element->getFont()->getName()); - $objWriter->endElement(); + if ($element->getFont()->getName() !== null) { + $objWriter->startElement($prefix . 'rFont'); + $objWriter->writeAttribute('val', $element->getFont()->getName()); + $objWriter->endElement(); + } // Bold $objWriter->startElement($prefix . 'b'); @@ -166,19 +168,25 @@ class StringTable extends WriterPart $objWriter->endElement(); // Color - $objWriter->startElement($prefix . 'color'); - $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); - $objWriter->endElement(); + if ($element->getFont()->getColor()->getARGB() !== null) { + $objWriter->startElement($prefix . 'color'); + $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); + $objWriter->endElement(); + } // Size - $objWriter->startElement($prefix . 'sz'); - $objWriter->writeAttribute('val', $element->getFont()->getSize()); - $objWriter->endElement(); + if ($element->getFont()->getSize() !== null) { + $objWriter->startElement($prefix . 'sz'); + $objWriter->writeAttribute('val', (string) $element->getFont()->getSize()); + $objWriter->endElement(); + } // Underline - $objWriter->startElement($prefix . 'u'); - $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); - $objWriter->endElement(); + if ($element->getFont()->getUnderline() !== null) { + $objWriter->startElement($prefix . 'u'); + $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -201,10 +209,10 @@ class StringTable extends WriterPart */ public function writeRichTextForCharts(XMLWriter $objWriter, $richText = null, $prefix = ''): void { - if (!$richText instanceof RichText) { + if (!($richText instanceof RichText)) { $textRun = $richText; $richText = new RichText(); - $run = $richText->createTextRun($textRun); + $run = $richText->createTextRun($textRun ?? ''); $run->setFont(null); } @@ -226,9 +234,9 @@ class StringTable extends WriterPart } // Bold - $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); + $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? '1' : '0')); // Italic - $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); + $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? '1' : '0')); // Underline $underlineType = $element->getFont()->getUnderline(); switch ($underlineType) { @@ -241,7 +249,9 @@ class StringTable extends WriterPart break; } - $objWriter->writeAttribute('u', $underlineType); + if ($underlineType !== null) { + $objWriter->writeAttribute('u', $underlineType); + } // Strikethrough $objWriter->writeAttribute('strike', ($element->getFont()->getStriketype() ?: 'noStrike')); // Superscript/subscript diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php index cb2e38504..0442c25d4 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Style.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Borders; use PhpOffice\PhpSpreadsheet\Style\Conditional; @@ -40,7 +41,7 @@ class Style extends WriterPart // numFmts $objWriter->startElement('numFmts'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); + $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getNumFmtHashTable()->count()); // numFmt for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { @@ -51,54 +52,63 @@ class Style extends WriterPart // fonts $objWriter->startElement('fonts'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); + $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getFontHashTable()->count()); // font for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { - $this->writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); + $thisfont = $this->getParentWriter()->getFontHashTable()->getByIndex($i); + if ($thisfont !== null) { + $this->writeFont($objWriter, $thisfont); + } } $objWriter->endElement(); // fills $objWriter->startElement('fills'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); + $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getFillHashTable()->count()); // fill for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { - $this->writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); + $thisfill = $this->getParentWriter()->getFillHashTable()->getByIndex($i); + if ($thisfill !== null) { + $this->writeFill($objWriter, $thisfill); + } } $objWriter->endElement(); // borders $objWriter->startElement('borders'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); + $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getBordersHashTable()->count()); // border for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { - $this->writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); + $thisborder = $this->getParentWriter()->getBordersHashTable()->getByIndex($i); + if ($thisborder !== null) { + $this->writeBorder($objWriter, $thisborder); + } } $objWriter->endElement(); // cellStyleXfs $objWriter->startElement('cellStyleXfs'); - $objWriter->writeAttribute('count', 1); + $objWriter->writeAttribute('count', '1'); // xf $objWriter->startElement('xf'); - $objWriter->writeAttribute('numFmtId', 0); - $objWriter->writeAttribute('fontId', 0); - $objWriter->writeAttribute('fillId', 0); - $objWriter->writeAttribute('borderId', 0); + $objWriter->writeAttribute('numFmtId', '0'); + $objWriter->writeAttribute('fontId', '0'); + $objWriter->writeAttribute('fillId', '0'); + $objWriter->writeAttribute('borderId', '0'); $objWriter->endElement(); $objWriter->endElement(); // cellXfs $objWriter->startElement('cellXfs'); - $objWriter->writeAttribute('count', count($spreadsheet->getCellXfCollection())); + $objWriter->writeAttribute('count', (string) count($spreadsheet->getCellXfCollection())); // xf foreach ($spreadsheet->getCellXfCollection() as $cellXf) { @@ -109,24 +119,27 @@ class Style extends WriterPart // cellStyles $objWriter->startElement('cellStyles'); - $objWriter->writeAttribute('count', 1); + $objWriter->writeAttribute('count', '1'); // cellStyle $objWriter->startElement('cellStyle'); $objWriter->writeAttribute('name', 'Normal'); - $objWriter->writeAttribute('xfId', 0); - $objWriter->writeAttribute('builtinId', 0); + $objWriter->writeAttribute('xfId', '0'); + $objWriter->writeAttribute('builtinId', '0'); $objWriter->endElement(); $objWriter->endElement(); // dxfs $objWriter->startElement('dxfs'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); + $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getStylesConditionalHashTable()->count()); // dxf for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { - $this->writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); + $thisstyle = $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i); + if ($thisstyle !== null) { + $this->writeCellStyleDxf($objWriter, $thisstyle->getStyle()); + } } $objWriter->endElement(); @@ -171,17 +184,19 @@ class Style extends WriterPart // gradientFill $objWriter->startElement('gradientFill'); - $objWriter->writeAttribute('type', $fill->getFillType()); - $objWriter->writeAttribute('degree', $fill->getRotation()); + $objWriter->writeAttribute('type', (string) $fill->getFillType()); + $objWriter->writeAttribute('degree', (string) $fill->getRotation()); // stop $objWriter->startElement('stop'); $objWriter->writeAttribute('position', '0'); // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB()); - $objWriter->endElement(); + if ($fill->getStartColor()->getARGB() !== null) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB()); + $objWriter->endElement(); + } $objWriter->endElement(); @@ -190,9 +205,11 @@ class Style extends WriterPart $objWriter->writeAttribute('position', '1'); // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $fill->getEndColor()->getARGB()); - $objWriter->endElement(); + if ($fill->getEndColor()->getARGB() !== null) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $fill->getEndColor()->getARGB()); + $objWriter->endElement(); + } $objWriter->endElement(); @@ -220,7 +237,7 @@ class Style extends WriterPart // patternFill $objWriter->startElement('patternFill'); - $objWriter->writeAttribute('patternType', $fill->getFillType()); + $objWriter->writeAttribute('patternType', (string) $fill->getFillType()); if (self::writePatternColors($fill)) { // fgColor @@ -360,20 +377,20 @@ class Style extends WriterPart { // xf $objWriter->startElement('xf'); - $objWriter->writeAttribute('xfId', 0); - $objWriter->writeAttribute('fontId', (int) $this->getParentWriter()->getFontHashTable()->getIndexForHashCode($style->getFont()->getHashCode())); + $objWriter->writeAttribute('xfId', '0'); + $objWriter->writeAttribute('fontId', (string) (int) $this->getParentWriter()->getFontHashTable()->getIndexForHashCode($style->getFont()->getHashCode())); if ($style->getQuotePrefix()) { - $objWriter->writeAttribute('quotePrefix', 1); + $objWriter->writeAttribute('quotePrefix', '1'); } if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { - $objWriter->writeAttribute('numFmtId', (int) ($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($style->getNumberFormat()->getHashCode()) + 164)); + $objWriter->writeAttribute('numFmtId', (string) (int) ($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($style->getNumberFormat()->getHashCode()) + 164)); } else { - $objWriter->writeAttribute('numFmtId', (int) $style->getNumberFormat()->getBuiltInFormatCode()); + $objWriter->writeAttribute('numFmtId', (string) (int) $style->getNumberFormat()->getBuiltInFormatCode()); } - $objWriter->writeAttribute('fillId', (int) $this->getParentWriter()->getFillHashTable()->getIndexForHashCode($style->getFill()->getHashCode())); - $objWriter->writeAttribute('borderId', (int) $this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($style->getBorders()->getHashCode())); + $objWriter->writeAttribute('fillId', (string) (int) $this->getParentWriter()->getFillHashTable()->getIndexForHashCode($style->getFill()->getHashCode())); + $objWriter->writeAttribute('borderId', (string) (int) $this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($style->getBorders()->getHashCode())); // Apply styles? $objWriter->writeAttribute('applyFont', ($spreadsheet->getDefaultStyle()->getFont()->getHashCode() != $style->getFont()->getHashCode()) ? '1' : '0'); @@ -387,25 +404,31 @@ class Style extends WriterPart // alignment $objWriter->startElement('alignment'); - $objWriter->writeAttribute('horizontal', $style->getAlignment()->getHorizontal()); - $objWriter->writeAttribute('vertical', $style->getAlignment()->getVertical()); + $vertical = Alignment::VERTICAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getVertical()] ?? ''; + $horizontal = Alignment::HORIZONTAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getHorizontal()] ?? ''; + if ($horizontal !== '') { + $objWriter->writeAttribute('horizontal', $horizontal); + } + if ($vertical !== '') { + $objWriter->writeAttribute('vertical', $vertical); + } $textRotation = 0; if ($style->getAlignment()->getTextRotation() >= 0) { $textRotation = $style->getAlignment()->getTextRotation(); - } elseif ($style->getAlignment()->getTextRotation() < 0) { + } else { $textRotation = 90 - $style->getAlignment()->getTextRotation(); } - $objWriter->writeAttribute('textRotation', $textRotation); + $objWriter->writeAttribute('textRotation', (string) $textRotation); $objWriter->writeAttribute('wrapText', ($style->getAlignment()->getWrapText() ? 'true' : 'false')); $objWriter->writeAttribute('shrinkToFit', ($style->getAlignment()->getShrinkToFit() ? 'true' : 'false')); if ($style->getAlignment()->getIndent() > 0) { - $objWriter->writeAttribute('indent', $style->getAlignment()->getIndent()); + $objWriter->writeAttribute('indent', (string) $style->getAlignment()->getIndent()); } if ($style->getAlignment()->getReadOrder() > 0) { - $objWriter->writeAttribute('readingOrder', $style->getAlignment()->getReadOrder()); + $objWriter->writeAttribute('readingOrder', (string) $style->getAlignment()->getReadOrder()); } $objWriter->endElement(); @@ -443,21 +466,23 @@ class Style extends WriterPart // alignment $objWriter->startElement('alignment'); - if ($style->getAlignment()->getHorizontal() !== null) { - $objWriter->writeAttribute('horizontal', $style->getAlignment()->getHorizontal()); + $horizontal = Alignment::HORIZONTAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getHorizontal()] ?? ''; + if ($horizontal) { + $objWriter->writeAttribute('horizontal', $horizontal); } - if ($style->getAlignment()->getVertical() !== null) { - $objWriter->writeAttribute('vertical', $style->getAlignment()->getVertical()); + $vertical = Alignment::VERTICAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getVertical()] ?? ''; + if ($vertical) { + $objWriter->writeAttribute('vertical', $vertical); } if ($style->getAlignment()->getTextRotation() !== null) { $textRotation = 0; if ($style->getAlignment()->getTextRotation() >= 0) { $textRotation = $style->getAlignment()->getTextRotation(); - } elseif ($style->getAlignment()->getTextRotation() < 0) { + } else { $textRotation = 90 - $style->getAlignment()->getTextRotation(); } - $objWriter->writeAttribute('textRotation', $textRotation); + $objWriter->writeAttribute('textRotation', (string) $textRotation); } $objWriter->endElement(); @@ -465,7 +490,7 @@ class Style extends WriterPart $this->writeBorder($objWriter, $style->getBorders()); // protection - if (($style->getProtection()->getLocked() !== null) || ($style->getProtection()->getHidden() !== null)) { + if ((!empty($style->getProtection()->getLocked())) || (!empty($style->getProtection()->getHidden()))) { if ( $style->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT || $style->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT @@ -503,11 +528,13 @@ class Style extends WriterPart $objWriter->writeAttribute('style', $border->getBorderStyle()); // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $border->getColor()->getARGB()); - $objWriter->endElement(); + if ($border->getColor()->getARGB() !== null) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $border->getColor()->getARGB()); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); + } } } @@ -516,15 +543,15 @@ class Style extends WriterPart * * @param int $id Number Format identifier */ - private function writeNumFmt(XMLWriter $objWriter, NumberFormat $numberFormat, $id = 0): void + private function writeNumFmt(XMLWriter $objWriter, ?NumberFormat $numberFormat, $id = 0): void { // Translate formatcode - $formatCode = $numberFormat->getFormatCode(); + $formatCode = ($numberFormat === null) ? null : $numberFormat->getFormatCode(); // numFmt if ($formatCode !== null) { $objWriter->startElement('numFmt'); - $objWriter->writeAttribute('numFmtId', ($id + 164)); + $objWriter->writeAttribute('numFmtId', (string) ($id + 164)); $objWriter->writeAttribute('formatCode', $formatCode); $objWriter->endElement(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php index f9d7197d7..7d08388da 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php @@ -104,14 +104,14 @@ class Workbook extends WriterPart // workbookView $objWriter->startElement('workbookView'); - $objWriter->writeAttribute('activeTab', $spreadsheet->getActiveSheetIndex()); + $objWriter->writeAttribute('activeTab', (string) $spreadsheet->getActiveSheetIndex()); $objWriter->writeAttribute('autoFilterDateGrouping', ($spreadsheet->getAutoFilterDateGrouping() ? 'true' : 'false')); - $objWriter->writeAttribute('firstSheet', $spreadsheet->getFirstSheetIndex()); + $objWriter->writeAttribute('firstSheet', (string) $spreadsheet->getFirstSheetIndex()); $objWriter->writeAttribute('minimized', ($spreadsheet->getMinimized() ? 'true' : 'false')); $objWriter->writeAttribute('showHorizontalScroll', ($spreadsheet->getShowHorizontalScroll() ? 'true' : 'false')); $objWriter->writeAttribute('showSheetTabs', ($spreadsheet->getShowSheetTabs() ? 'true' : 'false')); $objWriter->writeAttribute('showVerticalScroll', ($spreadsheet->getShowVerticalScroll() ? 'true' : 'false')); - $objWriter->writeAttribute('tabRatio', $spreadsheet->getTabRatio()); + $objWriter->writeAttribute('tabRatio', (string) $spreadsheet->getTabRatio()); $objWriter->writeAttribute('visibility', $spreadsheet->getVisibility()); $objWriter->endElement(); @@ -157,9 +157,9 @@ class Workbook extends WriterPart $objWriter->writeAttribute('calcId', '999999'); $objWriter->writeAttribute('calcMode', 'auto'); // fullCalcOnLoad isn't needed if we've recalculating for the save - $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); - $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); - $objWriter->writeAttribute('forceFullCalc', ($recalcRequired) ? 0 : 1); + $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? '1' : '0'); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? '0' : '1'); + $objWriter->writeAttribute('forceFullCalc', ($recalcRequired) ? '0' : '1'); $objWriter->endElement(); } @@ -200,7 +200,7 @@ class Workbook extends WriterPart // Write sheet $objWriter->startElement('sheet'); $objWriter->writeAttribute('name', $worksheetName); - $objWriter->writeAttribute('sheetId', $worksheetId); + $objWriter->writeAttribute('sheetId', (string) $worksheetId); if ($sheetState !== 'visible' && $sheetState != '') { $objWriter->writeAttribute('state', $sheetState); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index f6c0c035c..1aa4f1ca3 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -28,7 +28,7 @@ class Worksheet extends WriterPart * * @return string XML Output */ - public function writeWorksheet(PhpspreadsheetWorksheet $worksheet, $stringTable = null, $includeCharts = false) + public function writeWorksheet(PhpspreadsheetWorksheet $worksheet, $stringTable = [], $includeCharts = false) { // Create XML writer $objWriter = null; @@ -149,7 +149,7 @@ class Worksheet extends WriterPart } $autoFilterRange = $worksheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { - $objWriter->writeAttribute('filterMode', 1); + $objWriter->writeAttribute('filterMode', '1'); if (!$worksheet->getAutoFilter()->getEvaluated()) { $worksheet->getAutoFilter()->showHideRows(); } @@ -158,7 +158,7 @@ class Worksheet extends WriterPart // tabColor if ($worksheet->isTabColorSet()) { $objWriter->startElement('tabColor'); - $objWriter->writeAttribute('rgb', $worksheet->getTabColor()->getARGB()); + $objWriter->writeAttribute('rgb', $worksheet->getTabColor()->getARGB() ?? ''); $objWriter->endElement(); } @@ -218,7 +218,7 @@ class Worksheet extends WriterPart // Show zeros (Excel also writes this attribute only if set to false) if ($worksheet->getSheetView()->getShowZeros() === false) { - $objWriter->writeAttribute('showZeros', 0); + $objWriter->writeAttribute('showZeros', '0'); } // View Layout Type @@ -252,7 +252,7 @@ class Worksheet extends WriterPart // Pane $pane = ''; if ($worksheet->getFreezePane()) { - [$xSplit, $ySplit] = Coordinate::coordinateFromString($worksheet->getFreezePane() ?? ''); + [$xSplit, $ySplit] = Coordinate::coordinateFromString($worksheet->getFreezePane()); $xSplit = Coordinate::columnIndexFromString($xSplit); --$xSplit; --$ySplit; @@ -261,7 +261,7 @@ class Worksheet extends WriterPart $pane = 'topRight'; $objWriter->startElement('pane'); if ($xSplit > 0) { - $objWriter->writeAttribute('xSplit', $xSplit); + $objWriter->writeAttribute('xSplit', "$xSplit"); } if ($ySplit > 0) { $objWriter->writeAttribute('ySplit', $ySplit); @@ -334,7 +334,7 @@ class Worksheet extends WriterPart $outlineLevelRow = $dimension->getOutlineLevel(); } } - $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow); + $objWriter->writeAttribute('outlineLevelRow', (string) (int) $outlineLevelRow); // Outline level - column $outlineLevelCol = 0; @@ -343,7 +343,7 @@ class Worksheet extends WriterPart $outlineLevelCol = $dimension->getOutlineLevel(); } } - $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol); + $objWriter->writeAttribute('outlineLevelCol', (string) (int) $outlineLevelCol); $objWriter->endElement(); } @@ -363,8 +363,8 @@ class Worksheet extends WriterPart foreach ($worksheet->getColumnDimensions() as $colDimension) { // col $objWriter->startElement('col'); - $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex())); - $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex())); + $objWriter->writeAttribute('min', (string) Coordinate::columnIndexFromString($colDimension->getColumnIndex())); + $objWriter->writeAttribute('max', (string) Coordinate::columnIndexFromString($colDimension->getColumnIndex())); if ($colDimension->getWidth() < 0) { // No width set, apply default of 10 @@ -396,11 +396,11 @@ class Worksheet extends WriterPart // Outline level if ($colDimension->getOutlineLevel() > 0) { - $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); + $objWriter->writeAttribute('outlineLevel', (string) $colDimension->getOutlineLevel()); } // Style - $objWriter->writeAttribute('style', $colDimension->getXfIndex()); + $objWriter->writeAttribute('style', (string) $colDimension->getXfIndex()); $objWriter->endElement(); } @@ -423,7 +423,7 @@ class Worksheet extends WriterPart $objWriter->writeAttribute('algorithmName', $protection->getAlgorithm()); $objWriter->writeAttribute('hashValue', $protection->getPassword()); $objWriter->writeAttribute('saltValue', $protection->getSalt()); - $objWriter->writeAttribute('spinCount', $protection->getSpinCount()); + $objWriter->writeAttribute('spinCount', (string) $protection->getSpinCount()); } elseif ($protection->getPassword() !== '') { $objWriter->writeAttribute('password', $protection->getPassword()); } @@ -447,7 +447,7 @@ class Worksheet extends WriterPart $objWriter->endElement(); } - private static function writeAttributeIf(XMLWriter $objWriter, $condition, string $attr, string $val): void + private static function writeAttributeIf(XMLWriter $objWriter, ?bool $condition, string $attr, string $val): void { if ($condition) { $objWriter->writeAttribute($attr, $val); @@ -461,7 +461,7 @@ class Worksheet extends WriterPart } } - private static function writeElementIf(XMLWriter $objWriter, $condition, string $attr, string $val): void + private static function writeElementIf(XMLWriter $objWriter, bool $condition, string $attr, string $val): void { if ($condition) { $objWriter->writeElement($attr, $val); @@ -503,7 +503,7 @@ class Worksheet extends WriterPart private static function writeTimePeriodCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void { $txt = $conditional->getText(); - if ($txt !== null) { + if (!empty($txt)) { $objWriter->writeAttribute('timePeriod', $txt); if (empty($conditional->getConditions())) { if ($conditional->getOperatorType() == Conditional::TIMEPERIOD_TODAY) { @@ -536,7 +536,7 @@ class Worksheet extends WriterPart private static function writeTextCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void { $txt = $conditional->getText(); - if ($txt !== null) { + if (!empty($txt)) { $objWriter->writeAttribute('text', $txt); if (empty($conditional->getConditions())) { if ($conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT) { @@ -568,7 +568,7 @@ class Worksheet extends WriterPart $objWriter->writeAttribute($attrKey, $val); } $minCfvo = $dataBar->getMinimumConditionalFormatValueObject(); - if ($minCfvo) { + if ($minCfvo !== null) { $objWriter->startElementNs($prefix, 'cfvo', null); $objWriter->writeAttribute('type', $minCfvo->getType()); if ($minCfvo->getCellFormula()) { @@ -578,7 +578,7 @@ class Worksheet extends WriterPart } $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject(); - if ($maxCfvo) { + if ($maxCfvo !== null) { $objWriter->startElementNs($prefix, 'cfvo', null); $objWriter->writeAttribute('type', $maxCfvo->getType()); if ($maxCfvo->getCellFormula()) { @@ -600,9 +600,8 @@ class Worksheet extends WriterPart $objWriter->endElement(); //end conditionalFormatting } - private static function writeDataBarElements(XMLWriter $objWriter, $dataBar): void + private static function writeDataBarElements(XMLWriter $objWriter, ?ConditionalDataBar $dataBar): void { - /** @var ConditionalDataBar $dataBar */ if ($dataBar) { $objWriter->startElement('dataBar'); self::writeAttributeIf($objWriter, null !== $dataBar->getShowValue(), 'showValue', $dataBar->getShowValue() ? '1' : '0'); @@ -669,7 +668,7 @@ class Worksheet extends WriterPart 'dxfId', (string) $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) ); - $objWriter->writeAttribute('priority', $id++); + $objWriter->writeAttribute('priority', (string) $id++); self::writeAttributeif( $objWriter, @@ -724,7 +723,7 @@ class Worksheet extends WriterPart if (!empty($dataValidationCollection)) { $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection); $objWriter->startElement('dataValidations'); - $objWriter->writeAttribute('count', count($dataValidationCollection)); + $objWriter->writeAttribute('count', (string) count($dataValidationCollection)); foreach ($dataValidationCollection as $coordinate => $dv) { $objWriter->startElement('dataValidation'); @@ -922,11 +921,11 @@ class Worksheet extends WriterPart $rules = $column->getRules(); if (count($rules) > 0) { $objWriter->startElement('filterColumn'); - $objWriter->writeAttribute('colId', $worksheet->getAutoFilter()->getColumnOffset($columnID)); + $objWriter->writeAttribute('colId', (string) $worksheet->getAutoFilter()->getColumnOffset($columnID)); $objWriter->startElement($column->getFilterType()); if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) { - $objWriter->writeAttribute('and', 1); + $objWriter->writeAttribute('and', '1'); } foreach ($rules as $rule) { @@ -936,7 +935,7 @@ class Worksheet extends WriterPart ($rule->getValue() === '') ) { // Filter rule for Blanks - $objWriter->writeAttribute('blank', 1); + $objWriter->writeAttribute('blank', '1'); } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { // Dynamic Filter Rule $objWriter->writeAttribute('type', $rule->getGrouping()); @@ -1019,24 +1018,24 @@ class Worksheet extends WriterPart { // pageSetup $objWriter->startElement('pageSetup'); - $objWriter->writeAttribute('paperSize', $worksheet->getPageSetup()->getPaperSize()); + $objWriter->writeAttribute('paperSize', (string) $worksheet->getPageSetup()->getPaperSize()); $objWriter->writeAttribute('orientation', $worksheet->getPageSetup()->getOrientation()); if ($worksheet->getPageSetup()->getScale() !== null) { - $objWriter->writeAttribute('scale', $worksheet->getPageSetup()->getScale()); + $objWriter->writeAttribute('scale', (string) $worksheet->getPageSetup()->getScale()); } if ($worksheet->getPageSetup()->getFitToHeight() !== null) { - $objWriter->writeAttribute('fitToHeight', $worksheet->getPageSetup()->getFitToHeight()); + $objWriter->writeAttribute('fitToHeight', (string) $worksheet->getPageSetup()->getFitToHeight()); } else { $objWriter->writeAttribute('fitToHeight', '0'); } if ($worksheet->getPageSetup()->getFitToWidth() !== null) { - $objWriter->writeAttribute('fitToWidth', $worksheet->getPageSetup()->getFitToWidth()); + $objWriter->writeAttribute('fitToWidth', (string) $worksheet->getPageSetup()->getFitToWidth()); } else { $objWriter->writeAttribute('fitToWidth', '0'); } - if ($worksheet->getPageSetup()->getFirstPageNumber() !== null) { - $objWriter->writeAttribute('firstPageNumber', $worksheet->getPageSetup()->getFirstPageNumber()); + if (!empty($worksheet->getPageSetup()->getFirstPageNumber())) { + $objWriter->writeAttribute('firstPageNumber', (string) $worksheet->getPageSetup()->getFirstPageNumber()); $objWriter->writeAttribute('useFirstPageNumber', '1'); } $objWriter->writeAttribute('pageOrder', $worksheet->getPageSetup()->getPageOrder()); @@ -1089,8 +1088,8 @@ class Worksheet extends WriterPart // rowBreaks if (!empty($aRowBreaks)) { $objWriter->startElement('rowBreaks'); - $objWriter->writeAttribute('count', count($aRowBreaks)); - $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); + $objWriter->writeAttribute('count', (string) count($aRowBreaks)); + $objWriter->writeAttribute('manualBreakCount', (string) count($aRowBreaks)); foreach ($aRowBreaks as $cell) { $coords = Coordinate::coordinateFromString($cell); @@ -1107,14 +1106,14 @@ class Worksheet extends WriterPart // Second, write column breaks if (!empty($aColumnBreaks)) { $objWriter->startElement('colBreaks'); - $objWriter->writeAttribute('count', count($aColumnBreaks)); - $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); + $objWriter->writeAttribute('count', (string) count($aColumnBreaks)); + $objWriter->writeAttribute('manualBreakCount', (string) count($aColumnBreaks)); foreach ($aColumnBreaks as $cell) { $coords = Coordinate::coordinateFromString($cell); $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1); + $objWriter->writeAttribute('id', (string) (Coordinate::columnIndexFromString($coords[0]) - 1)); $objWriter->writeAttribute('man', '1'); $objWriter->endElement(); } @@ -1155,58 +1154,61 @@ class Worksheet extends WriterPart $currentRow = 0; while ($currentRow++ < $highestRow) { - // Get row dimension - $rowDimension = $worksheet->getRowDimension($currentRow); + $isRowSet = isset($cellsByRow[$currentRow]); + if ($isRowSet || $worksheet->rowDimensionExists($currentRow)) { + // Get row dimension + $rowDimension = $worksheet->getRowDimension($currentRow); - // Write current row? - $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() === false || $rowDimension->getCollapsed() === true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null; + // Write current row? + $writeCurrentRow = $isRowSet || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() === false || $rowDimension->getCollapsed() === true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null; - if ($writeCurrentRow) { - // Start a new row - $objWriter->startElement('row'); - $objWriter->writeAttribute('r', $currentRow); - $objWriter->writeAttribute('spans', '1:' . $colCount); + if ($writeCurrentRow) { + // Start a new row + $objWriter->startElement('row'); + $objWriter->writeAttribute('r', "$currentRow"); + $objWriter->writeAttribute('spans', '1:' . $colCount); - // Row dimensions - if ($rowDimension->getRowHeight() >= 0) { - $objWriter->writeAttribute('customHeight', '1'); - $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight())); - } - - // Row visibility - if (!$rowDimension->getVisible() === true) { - $objWriter->writeAttribute('hidden', 'true'); - } - - // Collapsed - if ($rowDimension->getCollapsed() === true) { - $objWriter->writeAttribute('collapsed', 'true'); - } - - // Outline level - if ($rowDimension->getOutlineLevel() > 0) { - $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); - } - - // Style - if ($rowDimension->getXfIndex() !== null) { - $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); - $objWriter->writeAttribute('customFormat', '1'); - } - - // Write cells - if (isset($cellsByRow[$currentRow])) { - // We have a comma-separated list of column names (with a trailing entry); split to an array - $columnsInRow = explode(',', $cellsByRow[$currentRow]); - array_pop($columnsInRow); - foreach ($columnsInRow as $column) { - // Write cell - $this->writeCell($objWriter, $worksheet, "{$column}{$currentRow}", $aFlippedStringTable); + // Row dimensions + if ($rowDimension->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', '1'); + $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight())); } - } - // End row - $objWriter->endElement(); + // Row visibility + if (!$rowDimension->getVisible() === true) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Collapsed + if ($rowDimension->getCollapsed() === true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($rowDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', (string) $rowDimension->getOutlineLevel()); + } + + // Style + if ($rowDimension->getXfIndex() !== null) { + $objWriter->writeAttribute('s', (string) $rowDimension->getXfIndex()); + $objWriter->writeAttribute('customFormat', '1'); + } + + // Write cells + if (isset($cellsByRow[$currentRow])) { + // We have a comma-separated list of column names (with a trailing entry); split to an array + $columnsInRow = explode(',', $cellsByRow[$currentRow]); + array_pop($columnsInRow); + foreach ($columnsInRow as $column) { + // Write cell + $this->writeCell($objWriter, $worksheet, "{$column}{$currentRow}", $aFlippedStringTable); + } + } + + // End row + $objWriter->endElement(); + } } } @@ -1226,7 +1228,7 @@ class Worksheet extends WriterPart StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue, Settings::htmlEntityFlags())) ); $objWriter->endElement(); - } elseif ($cellValue instanceof RichText) { + } else { $objWriter->startElement('is'); $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue); $objWriter->endElement(); @@ -1260,7 +1262,7 @@ class Worksheet extends WriterPart $cellValue = $cellValue . '.0'; } } - $objWriter->writeElement('v', $cellValue); + $objWriter->writeElement('v', "$cellValue"); } private function writeCellBoolean(XMLWriter $objWriter, string $mappedType, bool $cellValue): void @@ -1329,7 +1331,7 @@ class Worksheet extends WriterPart // Sheet styles $xfi = $pCell->getXfIndex(); - self::writeAttributeIf($objWriter, $xfi, 's', $xfi); + self::writeAttributeIf($objWriter, (bool) $xfi, 's', "$xfi"); // If cell value is supplied, write cell value $cellValue = $pCell->getValue(); @@ -1446,7 +1448,6 @@ class Worksheet extends WriterPart /** @var Conditional $conditional */ foreach ($conditionalStyles as $conditional) { $dataBar = $conditional->getDataBar(); - // @phpstan-ignore-next-line if ($dataBar && $dataBar->getConditionalFormattingRuleExt()) { $conditionalFormattingRuleExtList[] = $dataBar->getConditionalFormattingRuleExt(); } diff --git a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php index 6fc0c66a5..a1bdf96a5 100644 --- a/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php +++ b/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php @@ -144,6 +144,9 @@ class Xlfn . '|call' . '|let' . '|register[.]id' + . '|textafter' + . '|textbefore' + . '|textsplit' . '|valuetotext' . ')(?=\\s*[(])/i'; diff --git a/vendor/psr/cache/CHANGELOG.md b/vendor/psr/cache/CHANGELOG.md deleted file mode 100644 index 58ddab05a..000000000 --- a/vendor/psr/cache/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file, in reverse chronological order by release. - -## 1.0.1 - 2016-08-06 - -### Fixed - -- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr -- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr -- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell -- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell - -## 1.0.0 - 2015-12-11 - -Initial stable release; reflects accepted PSR-6 specification diff --git a/vendor/psr/cache/LICENSE.txt b/vendor/psr/cache/LICENSE.txt deleted file mode 100644 index b1c2c97b9..000000000 --- a/vendor/psr/cache/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 PHP Framework Interoperability Group - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/psr/cache/README.md b/vendor/psr/cache/README.md deleted file mode 100644 index c8706ceea..000000000 --- a/vendor/psr/cache/README.md +++ /dev/null @@ -1,9 +0,0 @@ -PSR Cache -========= - -This repository holds all interfaces defined by -[PSR-6](http://www.php-fig.org/psr/psr-6/). - -Note that this is not a Cache implementation of its own. It is merely an -interface that describes a Cache implementation. See the specification for more -details. diff --git a/vendor/psr/cache/composer.json b/vendor/psr/cache/composer.json deleted file mode 100644 index e828fec94..000000000 --- a/vendor/psr/cache/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "psr/cache", - "description": "Common interface for caching libraries", - "keywords": ["psr", "psr-6", "cache"], - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - } -} diff --git a/vendor/psr/cache/src/CacheException.php b/vendor/psr/cache/src/CacheException.php deleted file mode 100644 index e27f22f8d..000000000 --- a/vendor/psr/cache/src/CacheException.php +++ /dev/null @@ -1,10 +0,0 @@ - 'think\\app\\Service', diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php index 693749f22..bce5c4a84 100644 --- a/vendor/symfony/polyfill-mbstring/Mbstring.php +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -80,7 +80,7 @@ final class Mbstring public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { - if (\is_array($fromEncoding) || ($fromEncoding !== null && false !== strpos($fromEncoding, ','))) { + if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); } else { $fromEncoding = self::getEncoding($fromEncoding); @@ -102,7 +102,7 @@ final class Mbstring $fromEncoding = 'Windows-1252'; } if ('UTF-8' !== $fromEncoding) { - $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s); + $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); } return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); @@ -113,7 +113,7 @@ final class Mbstring $fromEncoding = 'UTF-8'; } - return \iconv($fromEncoding, $toEncoding.'//IGNORE', $s); + return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); } public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) @@ -130,7 +130,7 @@ final class Mbstring public static function mb_decode_mimeheader($s) { - return \iconv_mime_decode($s, 2, self::$internalEncoding); + return iconv_mime_decode($s, 2, self::$internalEncoding); } public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) @@ -140,7 +140,7 @@ final class Mbstring public static function mb_decode_numericentity($s, $convmap, $encoding = null) { - if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); return null; @@ -150,7 +150,7 @@ final class Mbstring return false; } - if (null !== $encoding && !is_scalar($encoding)) { + if (null !== $encoding && !\is_scalar($encoding)) { trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); return ''; // Instead of null (cf. mb_encode_numericentity). @@ -166,10 +166,10 @@ final class Mbstring if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $s)) { - $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); } } else { - $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + $s = iconv($encoding, 'UTF-8//IGNORE', $s); } $cnt = floor(\count($convmap) / 4) * 4; @@ -195,12 +195,12 @@ final class Mbstring return $s; } - return \iconv('UTF-8', $encoding.'//IGNORE', $s); + return iconv('UTF-8', $encoding.'//IGNORE', $s); } public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) { - if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); return null; @@ -210,13 +210,13 @@ final class Mbstring return false; } - if (null !== $encoding && !is_scalar($encoding)) { + if (null !== $encoding && !\is_scalar($encoding)) { trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); return null; // Instead of '' (cf. mb_decode_numericentity). } - if (null !== $is_hex && !is_scalar($is_hex)) { + if (null !== $is_hex && !\is_scalar($is_hex)) { trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING); return null; @@ -232,10 +232,10 @@ final class Mbstring if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $s)) { - $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); } } else { - $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + $s = iconv($encoding, 'UTF-8//IGNORE', $s); } static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; @@ -265,7 +265,7 @@ final class Mbstring return $result; } - return \iconv('UTF-8', $encoding.'//IGNORE', $result); + return iconv('UTF-8', $encoding.'//IGNORE', $result); } public static function mb_convert_case($s, $mode, $encoding = null) @@ -280,10 +280,10 @@ final class Mbstring if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $s)) { - $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); } } else { - $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + $s = iconv($encoding, 'UTF-8//IGNORE', $s); } if (\MB_CASE_TITLE == $mode) { @@ -343,7 +343,7 @@ final class Mbstring return $s; } - return \iconv('UTF-8', $encoding.'//IGNORE', $s); + return iconv('UTF-8', $encoding.'//IGNORE', $s); } public static function mb_internal_encoding($encoding = null) @@ -354,7 +354,7 @@ final class Mbstring $normalizedEncoding = self::getEncoding($encoding); - if ('UTF-8' === $normalizedEncoding || false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) { + if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { self::$internalEncoding = $normalizedEncoding; return true; @@ -413,7 +413,7 @@ final class Mbstring $encoding = self::$internalEncoding; } - return self::mb_detect_encoding($var, [$encoding]) || false !== @\iconv($encoding, $encoding, $var); + return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); } public static function mb_detect_encoding($str, $encodingList = null, $strict = false) @@ -488,7 +488,7 @@ final class Mbstring return \strlen($s); } - return @\iconv_strlen($s, $encoding); + return @iconv_strlen($s, $encoding); } public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) @@ -509,7 +509,7 @@ final class Mbstring return 0; } - return \iconv_strpos($haystack, $needle, $offset, $encoding); + return iconv_strpos($haystack, $needle, $offset, $encoding); } public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) @@ -533,7 +533,7 @@ final class Mbstring } $pos = '' !== $needle || 80000 > \PHP_VERSION_ID - ? \iconv_strrpos($haystack, $needle, $encoding) + ? iconv_strrpos($haystack, $needle, $encoding) : self::mb_strlen($haystack, $encoding); return false !== $pos ? $offset + $pos : false; @@ -541,7 +541,7 @@ final class Mbstring public static function mb_str_split($string, $split_length = 1, $encoding = null) { - if (null !== $string && !is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) { + if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) { trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING); return null; @@ -550,6 +550,7 @@ final class Mbstring if (1 > $split_length = (int) $split_length) { if (80000 > \PHP_VERSION_ID) { trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); + return false; } @@ -617,7 +618,7 @@ final class Mbstring } if ($start < 0) { - $start = \iconv_strlen($s, $encoding) + $start; + $start = iconv_strlen($s, $encoding) + $start; if ($start < 0) { $start = 0; } @@ -626,13 +627,13 @@ final class Mbstring if (null === $length) { $length = 2147483647; } elseif ($length < 0) { - $length = \iconv_strlen($s, $encoding) + $length - $start; + $length = iconv_strlen($s, $encoding) + $length - $start; if ($length < 0) { return ''; } } - return (string) \iconv_substr($s, $start, $length, $encoding); + return (string) iconv_substr($s, $start, $length, $encoding); } public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) @@ -657,7 +658,7 @@ final class Mbstring $pos = strrpos($haystack, $needle); } else { $needle = self::mb_substr($needle, 0, 1, $encoding); - $pos = \iconv_strrpos($haystack, $needle, $encoding); + $pos = iconv_strrpos($haystack, $needle, $encoding); } return self::getSubpart($pos, $part, $haystack, $encoding); @@ -736,12 +737,12 @@ final class Mbstring $encoding = self::getEncoding($encoding); if ('UTF-8' !== $encoding) { - $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + $s = iconv($encoding, 'UTF-8//IGNORE', $s); } $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); - return ($wide << 1) + \iconv_strlen($s, 'UTF-8'); + return ($wide << 1) + iconv_strlen($s, 'UTF-8'); } public static function mb_substr_count($haystack, $needle, $encoding = null) diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json index 9cd2e924e..44895536b 100644 --- a/vendor/symfony/polyfill-mbstring/composer.json +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -31,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-php72/Php72.php b/vendor/symfony/polyfill-php72/Php72.php index 5e20d5bf8..7bf96c996 100644 --- a/vendor/symfony/polyfill-php72/Php72.php +++ b/vendor/symfony/polyfill-php72/Php72.php @@ -83,7 +83,7 @@ final class Php72 'SunOS' => 'Solaris', ]; - return isset($map[\PHP_OS]) ? $map[\PHP_OS] : 'Unknown'; + return $map[\PHP_OS] ?? 'Unknown'; } public static function spl_object_id($object) @@ -96,7 +96,7 @@ final class Php72 } // On 32-bit systems, PHP_INT_SIZE is 4, - return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1))); + return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); } public static function sapi_windows_vt100_support($stream, $enable = null) @@ -167,7 +167,7 @@ final class Php72 self::$hashMask = (int) substr(ob_get_clean(), 17); } - self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1))); + self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); } public static function mb_chr($code, $encoding = null) diff --git a/vendor/symfony/polyfill-php72/composer.json b/vendor/symfony/polyfill-php72/composer.json index 4eac690e0..5f17af343 100644 --- a/vendor/symfony/polyfill-php72/composer.json +++ b/vendor/symfony/polyfill-php72/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php index 7ea6d2772..2b955423f 100644 --- a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +++ b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + #[Attribute(Attribute::TARGET_CLASS)] final class Attribute { diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php index 72f10812b..bd1212f6e 100644 --- a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +++ b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php @@ -1,6 +1,15 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) { class PhpToken extends Symfony\Polyfill\Php80\PhpToken { } diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php index 77e037cb5..7c62d7508 100644 --- a/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +++ b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + if (\PHP_VERSION_ID < 80000) { interface Stringable { diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php index 37937cbfa..01c6c6c8a 100644 --- a/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +++ b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + if (\PHP_VERSION_ID < 80000) { class UnhandledMatchError extends Error { diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php index a3a9b88b0..783dbc28c 100644 --- a/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +++ b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + if (\PHP_VERSION_ID < 80000) { class ValueError extends Error { diff --git a/vendor/symfony/polyfill-php80/composer.json b/vendor/symfony/polyfill-php80/composer.json index cd3e9b65f..bd9a3262a 100644 --- a/vendor/symfony/polyfill-php80/composer.json +++ b/vendor/symfony/polyfill-php80/composer.json @@ -30,7 +30,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/var-dumper/Resources/bin/var-dump-server b/vendor/symfony/var-dumper/Resources/bin/var-dump-server index 98c813a06..f398fcef7 100755 --- a/vendor/symfony/var-dumper/Resources/bin/var-dump-server +++ b/vendor/symfony/var-dumper/Resources/bin/var-dump-server @@ -10,6 +10,10 @@ * file that was distributed with this source code. */ +if ('cli' !== PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + /** * Starts a dump server to collect and output dumps on a single place with multiple formats support. * diff --git a/vendor/topthink/framework/README.md b/vendor/topthink/framework/README.md index aa16486e7..08893cd4f 100644 --- a/vendor/topthink/framework/README.md +++ b/vendor/topthink/framework/README.md @@ -1,6 +1,6 @@ ![](https://box.kancloud.cn/5a0aaa69a5ff42657b5c4715f3d49221) -ThinkPHP 6.0 +ThinkPHP 6.1 =============== [![Build Status](https://travis-ci.org/top-think/framework.svg?branch=6.0)](https://travis-ci.org/top-think/framework) @@ -11,9 +11,8 @@ ThinkPHP 6.0 [![PHP Version](https://img.shields.io/badge/php-%3E%3D7.1-8892BF.svg)](http://www.php.net/) [![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) -ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。 -[官方应用服务市场](https://market.topthink.com) | [`ThinkAPI`——官方统一API服务](https://docs.topthink.com/think-api/) +[官方服务](https://www.topthink.com) | [`ThinkAPI`——官方统一API](https://doc.topthink.com/think-api) ## 主要新特性 @@ -35,7 +34,7 @@ ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。 * 统一和精简大量用法 -> ThinkPHP6.0的运行环境要求PHP7.2+,兼容PHP8.1 +> ThinkPHP6.1的运行环境要求PHP7.2.5+,兼容PHP8.1 ## 安装 diff --git a/vendor/topthink/framework/composer.json b/vendor/topthink/framework/composer.json index 90793d3f1..b5cd915b7 100644 --- a/vendor/topthink/framework/composer.json +++ b/vendor/topthink/framework/composer.json @@ -22,8 +22,6 @@ "php": ">=7.2.5", "ext-json": "*", "ext-mbstring": "*", - "league/flysystem": "^1.1.4", - "league/flysystem-cached-adapter": "^1.0", "psr/log": "~1.0", "psr/container": "~1.0", "psr/simple-cache": "^1.0", diff --git a/vendor/topthink/framework/src/think/App.php b/vendor/topthink/framework/src/think/App.php index b189cd954..c7453b6a3 100644 --- a/vendor/topthink/framework/src/think/App.php +++ b/vendor/topthink/framework/src/think/App.php @@ -39,7 +39,7 @@ use think\initializer\RegisterService; */ class App extends Container { - const VERSION = '6.0.13LTS'; + const VERSION = '6.1.0'; /** * 应用调试模式 @@ -152,7 +152,6 @@ class App extends Container 'session' => Session::class, 'validate' => Validate::class, 'view' => View::class, - 'filesystem' => Filesystem::class, 'think\DbManager' => Db::class, 'think\LogManager' => Log::class, 'think\CacheManager' => Cache::class, diff --git a/vendor/topthink/framework/src/think/Console.php b/vendor/topthink/framework/src/think/Console.php index 389d104d5..27f12baad 100644 --- a/vendor/topthink/framework/src/think/Console.php +++ b/vendor/topthink/framework/src/think/Console.php @@ -117,9 +117,9 @@ class Console */ protected function makeRequest() { - $uri = $this->app->config->get('app.url', 'http://localhost'); + $url = $this->app->config->get('app.url', 'http://localhost'); - $components = parse_url($uri); + $components = parse_url($url); $server = $_SERVER; @@ -127,6 +127,7 @@ class Console $server = array_merge($server, [ 'SCRIPT_FILENAME' => $components['path'], 'SCRIPT_NAME' => $components['path'], + 'REQUEST_URI' => $components['path'], ]); } @@ -150,8 +151,6 @@ class Console $server['HTTP_HOST'] .= ':' . $components['port']; } - $server['REQUEST_URI'] = $uri; - /** @var Request $request */ $request = $this->app->make('request'); diff --git a/vendor/topthink/framework/src/think/Filesystem.php b/vendor/topthink/framework/src/think/Filesystem.php deleted file mode 100644 index 0aee929f5..000000000 --- a/vendor/topthink/framework/src/think/Filesystem.php +++ /dev/null @@ -1,89 +0,0 @@ - -// +---------------------------------------------------------------------- -declare (strict_types = 1); - -namespace think; - -use InvalidArgumentException; -use think\filesystem\Driver; -use think\filesystem\driver\Local; -use think\helper\Arr; - -/** - * Class Filesystem - * @package think - * @mixin Driver - * @mixin Local - */ -class Filesystem extends Manager -{ - protected $namespace = '\\think\\filesystem\\driver\\'; - - /** - * @param null|string $name - * @return Driver - */ - public function disk(string $name = null): Driver - { - return $this->driver($name); - } - - protected function resolveType(string $name) - { - return $this->getDiskConfig($name, 'type', 'local'); - } - - protected function resolveConfig(string $name) - { - return $this->getDiskConfig($name); - } - - /** - * 获取缓存配置 - * @access public - * @param null|string $name 名称 - * @param mixed $default 默认值 - * @return mixed - */ - public function getConfig(string $name = null, $default = null) - { - if (!is_null($name)) { - return $this->app->config->get('filesystem.' . $name, $default); - } - - return $this->app->config->get('filesystem'); - } - - /** - * 获取磁盘配置 - * @param string $disk - * @param null $name - * @param null $default - * @return array - */ - public function getDiskConfig($disk, $name = null, $default = null) - { - if ($config = $this->getConfig("disks.{$disk}")) { - return Arr::get($config, $name, $default); - } - - throw new InvalidArgumentException("Disk [$disk] not found."); - } - - /** - * 默认驱动 - * @return string|null - */ - public function getDefaultDriver() - { - return $this->getConfig('default'); - } -} diff --git a/vendor/topthink/framework/src/think/Lang.php b/vendor/topthink/framework/src/think/Lang.php index 5f16c464b..b89108482 100644 --- a/vendor/topthink/framework/src/think/Lang.php +++ b/vendor/topthink/framework/src/think/Lang.php @@ -287,58 +287,4 @@ class Lang return $value; } - /** - * 自动侦测设置获取语言选择 - * @deprecated - * @access public - * @param Request $request - * @return string - */ - public function detect(Request $request): string - { - // 自动侦测设置获取语言选择 - $langSet = ''; - - if ($request->get($this->config['detect_var'])) { - // url中设置了语言变量 - $langSet = strtolower($request->get($this->config['detect_var'])); - } elseif ($request->header($this->config['header_var'])) { - // Header中设置了语言变量 - $langSet = strtolower($request->header($this->config['header_var'])); - } elseif ($request->cookie($this->config['cookie_var'])) { - // Cookie中设置了语言变量 - $langSet = strtolower($request->cookie($this->config['cookie_var'])); - } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) { - // 自动侦测浏览器语言 - $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches); - if ($match) { - $langSet = strtolower($matches[1]); - if (isset($this->config['accept_language'][$langSet])) { - $langSet = $this->config['accept_language'][$langSet]; - } - } - } - - if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) { - // 合法的语言 - $this->range = $langSet; - } - - return $this->range; - } - - /** - * 保存当前语言到Cookie - * @deprecated - * @access public - * @param Cookie $cookie Cookie对象 - * @return void - */ - public function saveToCookie(Cookie $cookie) - { - if ($this->config['use_cookie']) { - $cookie->set($this->config['cookie_var'], $this->range); - } - } - } diff --git a/vendor/topthink/framework/src/think/facade/Filesystem.php b/vendor/topthink/framework/src/think/facade/Filesystem.php deleted file mode 100644 index 53706a841..000000000 --- a/vendor/topthink/framework/src/think/facade/Filesystem.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- -declare (strict_types = 1); - -namespace think\facade; - -use think\Facade; -use think\filesystem\Driver; - -/** - * Class Filesystem - * @package think\facade - * @mixin \think\Filesystem - * @method static Driver disk(string $name = null) ,null|string - * @method static mixed getConfig(null|string $name = null, mixed $default = null) 获取缓存配置 - * @method static array getDiskConfig(string $disk, null $name = null, null $default = null) 获取磁盘配置 - * @method static string|null getDefaultDriver() 默认驱动 - */ -class Filesystem extends Facade -{ - protected static function getFacadeClass() - { - return 'filesystem'; - } -} diff --git a/vendor/topthink/framework/src/think/filesystem/CacheStore.php b/vendor/topthink/framework/src/think/filesystem/CacheStore.php deleted file mode 100644 index 0a62399e0..000000000 --- a/vendor/topthink/framework/src/think/filesystem/CacheStore.php +++ /dev/null @@ -1,54 +0,0 @@ - -// +---------------------------------------------------------------------- -declare (strict_types = 1); - -namespace think\filesystem; - -use League\Flysystem\Cached\Storage\AbstractCache; -use Psr\SimpleCache\CacheInterface; - -class CacheStore extends AbstractCache -{ - protected $store; - - protected $key; - - protected $expire; - - public function __construct(CacheInterface $store, $key = 'flysystem', $expire = null) - { - $this->key = $key; - $this->store = $store; - $this->expire = $expire; - } - - /** - * Store the cache. - */ - public function save() - { - $contents = $this->getForStorage(); - - $this->store->set($this->key, $contents, $this->expire); - } - - /** - * Load the cache. - */ - public function load() - { - $contents = $this->store->get($this->key); - - if (!is_null($contents)) { - $this->setFromStorage($contents); - } - } -} diff --git a/vendor/topthink/framework/src/think/filesystem/Driver.php b/vendor/topthink/framework/src/think/filesystem/Driver.php deleted file mode 100644 index 0e61cf439..000000000 --- a/vendor/topthink/framework/src/think/filesystem/Driver.php +++ /dev/null @@ -1,144 +0,0 @@ - -// +---------------------------------------------------------------------- -declare (strict_types = 1); - -namespace think\filesystem; - -use League\Flysystem\AdapterInterface; -use League\Flysystem\Adapter\AbstractAdapter; -use League\Flysystem\Cached\CachedAdapter; -use League\Flysystem\Cached\Storage\Memory as MemoryStore; -use League\Flysystem\Filesystem; -use RuntimeException; -use think\Cache; -use think\File; - -/** - * Class Driver - * @package think\filesystem - * @mixin Filesystem - */ -abstract class Driver -{ - - /** @var Cache */ - protected $cache; - - /** @var Filesystem */ - protected $filesystem; - - /** - * 配置参数 - * @var array - */ - protected $config = []; - - public function __construct(Cache $cache, array $config) - { - $this->cache = $cache; - $this->config = array_merge($this->config, $config); - - $adapter = $this->createAdapter(); - $this->filesystem = $this->createFilesystem($adapter); - } - - protected function createCacheStore($config) - { - if (true === $config) { - return new MemoryStore; - } - - return new CacheStore( - $this->cache->store($config['store']), - $config['prefix'] ?? 'flysystem', - $config['expire'] ?? null - ); - } - - abstract protected function createAdapter(): AdapterInterface; - - protected function createFilesystem(AdapterInterface $adapter): Filesystem - { - if (!empty($this->config['cache'])) { - $adapter = new CachedAdapter($adapter, $this->createCacheStore($this->config['cache'])); - } - - $config = array_intersect_key($this->config, array_flip(['visibility', 'disable_asserts', 'url'])); - - return new Filesystem($adapter, count($config) > 0 ? $config : null); - } - - /** - * 获取文件完整路径 - * @param string $path - * @return string - */ - public function path(string $path): string - { - $adapter = $this->filesystem->getAdapter(); - - if ($adapter instanceof AbstractAdapter) { - return $adapter->applyPathPrefix($path); - } - - return $path; - } - - protected function concatPathToUrl($url, $path) - { - return rtrim($url, '/') . '/' . ltrim($path, '/'); - } - - public function url(string $path): string - { - throw new RuntimeException('This driver does not support retrieving URLs.'); - } - - /** - * 保存文件 - * @param string $path 路径 - * @param File $file 文件 - * @param null|string|\Closure $rule 文件名规则 - * @param array $options 参数 - * @return bool|string - */ - public function putFile(string $path, File $file, $rule = null, array $options = []) - { - return $this->putFileAs($path, $file, $file->hashName($rule), $options); - } - - /** - * 指定文件名保存文件 - * @param string $path 路径 - * @param File $file 文件 - * @param string $name 文件名 - * @param array $options 参数 - * @return bool|string - */ - public function putFileAs(string $path, File $file, string $name, array $options = []) - { - $stream = fopen($file->getRealPath(), 'r'); - $path = trim($path . '/' . $name, '/'); - - $result = $this->putStream($path, $stream, $options); - - if (is_resource($stream)) { - fclose($stream); - } - - return $result ? $path : false; - } - - public function __call($method, $parameters) - { - return $this->filesystem->$method(...$parameters); - } -} diff --git a/vendor/topthink/framework/src/think/filesystem/driver/Local.php b/vendor/topthink/framework/src/think/filesystem/driver/Local.php deleted file mode 100644 index 57493356d..000000000 --- a/vendor/topthink/framework/src/think/filesystem/driver/Local.php +++ /dev/null @@ -1,59 +0,0 @@ - -// +---------------------------------------------------------------------- -declare (strict_types = 1); - -namespace think\filesystem\driver; - -use League\Flysystem\AdapterInterface; -use League\Flysystem\Adapter\Local as LocalAdapter; -use think\filesystem\Driver; - -class Local extends Driver -{ - /** - * 配置参数 - * @var array - */ - protected $config = [ - 'root' => '', - ]; - - protected function createAdapter(): AdapterInterface - { - $permissions = $this->config['permissions'] ?? []; - - $links = ($this->config['links'] ?? null) === 'skip' - ? LocalAdapter::SKIP_LINKS - : LocalAdapter::DISALLOW_LINKS; - - return new LocalAdapter( - $this->config['root'], - LOCK_EX, - $links, - $permissions - ); - } - - /** - * 获取文件访问地址 - * @param string $path 文件路径 - * @return string - */ - public function url(string $path): string - { - $path = str_replace('\\', '/', $path); - - if (isset($this->config['url'])) { - return $this->concatPathToUrl($this->config['url'], $path); - } - return parent::url($path); - } -} diff --git a/vendor/topthink/framework/src/think/middleware/LoadLangPack.php b/vendor/topthink/framework/src/think/middleware/LoadLangPack.php index d6bf6a462..af0324b83 100644 --- a/vendor/topthink/framework/src/think/middleware/LoadLangPack.php +++ b/vendor/topthink/framework/src/think/middleware/LoadLangPack.php @@ -70,33 +70,35 @@ class LoadLangPack if ($request->get($this->config['detect_var'])) { // url中设置了语言变量 - $langSet = strtolower($request->get($this->config['detect_var'])); + $langSet = $request->get($this->config['detect_var']); } elseif ($request->header($this->config['header_var'])) { // Header中设置了语言变量 - $langSet = strtolower($request->header($this->config['header_var'])); + $langSet = $request->header($this->config['header_var']); } elseif ($request->cookie($this->config['cookie_var'])) { // Cookie中设置了语言变量 - $langSet = strtolower($request->cookie($this->config['cookie_var'])); + $langSet = $request->cookie($this->config['cookie_var']); } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) { // 自动侦测浏览器语言 - $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches); - if ($match) { - $langSet = strtolower($matches[1]); - if (isset($this->config['accept_language'][$langSet])) { - $langSet = $this->config['accept_language'][$langSet]; - } + $langSet = $request->server('HTTP_ACCEPT_LANGUAGE'); + } + + if (preg_match('/^([a-z\d\-]+)/i', $langSet, $matches)) { + $langSet = strtolower($matches[1]); + if (isset($this->config['accept_language'][$langSet])) { + $langSet = $this->config['accept_language'][$langSet]; } + } else { + $langSet = $this->lang->getLangSet(); } if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) { // 合法的语言 - $range = $langSet; - $this->lang->setLangSet($range); + $this->lang->setLangSet($langSet); } else { - $range = $this->lang->getLangSet(); + $langSet = $this->lang->getLangSet(); } - return $range; + return $langSet; } /** diff --git a/vendor/topthink/framework/tests/FilesystemTest.php b/vendor/topthink/framework/tests/FilesystemTest.php deleted file mode 100644 index df5ffe209..000000000 --- a/vendor/topthink/framework/tests/FilesystemTest.php +++ /dev/null @@ -1,131 +0,0 @@ -app = m::mock(App::class)->makePartial(); - Container::setInstance($this->app); - $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); - $this->config = m::mock(Config::class); - $this->config->shouldReceive('get')->with('filesystem.default', null)->andReturn('local'); - $this->app->shouldReceive('get')->with('config')->andReturn($this->config); - $this->filesystem = new Filesystem($this->app); - - $this->root = vfsStream::setup('rootDir'); - } - - protected function tearDown(): void - { - m::close(); - } - - public function testDisk() - { - $this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([ - 'type' => 'local', - 'root' => $this->root->url(), - ]); - - $this->config->shouldReceive('get')->with('filesystem.disks.foo', null)->andReturn([ - 'type' => 'local', - 'root' => $this->root->url(), - ]); - - $this->assertInstanceOf(Local::class, $this->filesystem->disk()); - - $this->assertInstanceOf(Local::class, $this->filesystem->disk('foo')); - } - - public function testCache() - { - $this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([ - 'type' => 'local', - 'root' => $this->root->url(), - 'cache' => true, - ]); - - $this->assertInstanceOf(Local::class, $this->filesystem->disk()); - - $this->config->shouldReceive('get')->with('filesystem.disks.cache', null)->andReturn([ - 'type' => NullDriver::class, - 'root' => $this->root->url(), - 'cache' => [ - 'store' => 'flysystem', - ], - ]); - - $cache = m::mock(Cache::class); - - $cacheDriver = m::mock(File::class); - - $cache->shouldReceive('store')->once()->with('flysystem')->andReturn($cacheDriver); - - $this->app->shouldReceive('make')->with(Cache::class)->andReturn($cache); - - $cacheDriver->shouldReceive('get')->with('flysystem')->once()->andReturn(null); - - $cacheDriver->shouldReceive('set')->withAnyArgs(); - - $this->filesystem->disk('cache')->put('test.txt', 'aa'); - } - - public function testPutFile() - { - $root = vfsStream::setup('rootDir', null, [ - 'foo.jpg' => 'hello', - ]); - - $this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([ - 'type' => NullDriver::class, - 'root' => $root->url(), - 'cache' => true, - ]); - - $file = m::mock(\think\File::class); - - $file->shouldReceive('hashName')->with(null)->once()->andReturn('foo.jpg'); - - $file->shouldReceive('getRealPath')->once()->andReturn($root->getChild('foo.jpg')->url()); - - $this->filesystem->putFile('test', $file); - } -} - -class NullDriver extends Driver -{ - protected function createAdapter(): AdapterInterface - { - return new NullAdapter(); - } -} diff --git a/vendor/topthink/think-multi-app/composer.json b/vendor/topthink/think-multi-app/composer.json index 92d620eb1..82606c1ef 100644 --- a/vendor/topthink/think-multi-app/composer.json +++ b/vendor/topthink/think-multi-app/composer.json @@ -10,7 +10,7 @@ ], "require": { "php": ">=7.1.0", - "topthink/framework": "^6.0.0" + "topthink/framework": "^6.0" }, "autoload": { "psr-4": { diff --git a/vendor/topthink/think-multi-app/src/Url.php b/vendor/topthink/think-multi-app/src/Url.php index 7bd6057f9..df415ad6e 100644 --- a/vendor/topthink/think-multi-app/src/Url.php +++ b/vendor/topthink/think-multi-app/src/Url.php @@ -42,15 +42,17 @@ class Url extends UrlBuild // 解析到控制器 $url = substr($url, 1); } elseif ('' === $url) { - $url = $this->getAppName() . '/' . $request->controller() . '/' . $request->action(); + $url = $request->controller() . '/' . $request->action(); + if (!$this->app->http->isBind()) { + $url = $this->getAppName() . '/' . $url; + } } else { // 解析到 应用/控制器/操作 $controller = $request->controller(); - $app = $this->getAppName(); $path = explode('/', $url); $action = array_pop($path); $controller = empty($path) ? $controller : array_pop($path); - $app = empty($path) ? $app : array_pop($path); + $app = empty($path) ? $this->getAppName() : array_pop($path); $url = $controller . '/' . $action; $bind = $this->app->config->get('app.domain_bind', []); @@ -58,7 +60,7 @@ class Url extends UrlBuild isset($bind[$_SERVER['SERVER_NAME']]) && $domain = $_SERVER['SERVER_NAME']; $domain = is_bool($domain) ? $key : $domain; - } else { + } elseif (!$this->app->http->isBind()) { $url = $app . '/' . $url; } } diff --git a/vendor/topthink/think-trace/composer.json b/vendor/topthink/think-trace/composer.json index 5af58545e..172a2d3c6 100644 --- a/vendor/topthink/think-trace/composer.json +++ b/vendor/topthink/think-trace/composer.json @@ -10,7 +10,7 @@ ], "require": { "php": ">=7.1.0", - "topthink/framework": "^6.0.0" + "topthink/framework": "^6.0" }, "autoload": { "psr-4": {