Merge branch 'master' into dedicated-interfaces
This commit is contained in:
commit
7dd91ee3ce
270
.github/workflows/ci.yml
vendored
Normal file
270
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
name: Spout CI
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests-on-php-latest:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
name: Tests - PHP 8.0 on ${{ matrix.operating-system }}
|
||||||
|
env:
|
||||||
|
extensions: zip, xmlreader, dom
|
||||||
|
cache-key: cache-matrix-v1 # can be any string, change to clear the extension cache.
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup cache environment
|
||||||
|
id: extcache
|
||||||
|
uses: shivammathur/cache-extensions@v1
|
||||||
|
with:
|
||||||
|
php-version: '8.0'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
key: ${{ env.cache-key }}
|
||||||
|
|
||||||
|
- name: Cache extensions
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.extcache.outputs.dir }}
|
||||||
|
key: ${{ steps.extcache.outputs.key }}
|
||||||
|
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
|
||||||
|
with:
|
||||||
|
php-version: '8.0'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- name: Cache composer dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
# Use composer.json for key, if composer.lock is not committed.
|
||||||
|
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Test with phpunit
|
||||||
|
run: vendor/bin/phpunit --no-coverage
|
||||||
|
|
||||||
|
tests-on-older-php:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-versions: ['7.3', '7.4']
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Tests - PHP ${{ matrix.php-versions }}
|
||||||
|
env:
|
||||||
|
extensions: zip, xmlreader, dom
|
||||||
|
cache-key: cache-matrix-v1 # can be any string, change to clear the extension cache.
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup cache environment
|
||||||
|
id: extcache
|
||||||
|
uses: shivammathur/cache-extensions@v1
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php-versions }}
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
key: ${{ env.cache-key }}
|
||||||
|
|
||||||
|
- name: Cache extensions
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.extcache.outputs.dir }}
|
||||||
|
key: ${{ steps.extcache.outputs.key }}
|
||||||
|
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php-versions }}
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- name: Cache composer dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
# Use composer.json for key, if composer.lock is not committed.
|
||||||
|
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Test with phpunit
|
||||||
|
run: vendor/bin/phpunit --no-coverage
|
||||||
|
|
||||||
|
code-coverage:
|
||||||
|
name: Code coverage
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
extensions: zip, xmlreader, dom
|
||||||
|
cache-key: cache-single-v1 # can be any string, change to clear the extension cache.
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup cache environment
|
||||||
|
id: extcache
|
||||||
|
uses: shivammathur/cache-extensions@v1
|
||||||
|
with:
|
||||||
|
php-version: '7.4'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
key: ${{ env.cache-key }}
|
||||||
|
|
||||||
|
- name: Cache extensions
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.extcache.outputs.dir }}
|
||||||
|
key: ${{ steps.extcache.outputs.key }}
|
||||||
|
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '7.4'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- name: Cache composer dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
# Use composer.json for key, if composer.lock is not committed.
|
||||||
|
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Run Tests with Code Coverage
|
||||||
|
run: |
|
||||||
|
mkdir -p build/logs
|
||||||
|
vendor/bin/phpunit --coverage-clover=build/logs/clover.xml
|
||||||
|
|
||||||
|
- name: Upload coverage results to Coveralls
|
||||||
|
env:
|
||||||
|
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
composer global require php-coveralls/php-coveralls
|
||||||
|
php-coveralls --coverage_clover=build/logs/clover.xml -v --exclude-no-stmt
|
||||||
|
|
||||||
|
coding-style:
|
||||||
|
name: Coding Style
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
extensions: zip, xmlreader, dom
|
||||||
|
cache-key: cache-single-v1 # can be any string, change to clear the extension cache.
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup cache environment
|
||||||
|
id: extcache
|
||||||
|
uses: shivammathur/cache-extensions@v1
|
||||||
|
with:
|
||||||
|
php-version: '8.0'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
key: ${{ env.cache-key }}
|
||||||
|
|
||||||
|
- name: Cache extensions
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.extcache.outputs.dir }}
|
||||||
|
key: ${{ steps.extcache.outputs.key }}
|
||||||
|
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '8.0'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- name: Cache composer dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
# Use composer.json for key, if composer.lock is not committed.
|
||||||
|
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Run PHP-CS-Fixer
|
||||||
|
run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run
|
||||||
|
|
||||||
|
static-analysis:
|
||||||
|
name: Static Analysis
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
extensions: zip, xmlreader, dom
|
||||||
|
cache-key: cache-single-v1 # can be any string, change to clear the extension cache.
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup cache environment
|
||||||
|
id: extcache
|
||||||
|
uses: shivammathur/cache-extensions@v1
|
||||||
|
with:
|
||||||
|
php-version: '8.0'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
key: ${{ env.cache-key }}
|
||||||
|
|
||||||
|
- name: Cache extensions
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.extcache.outputs.dir }}
|
||||||
|
key: ${{ steps.extcache.outputs.key }}
|
||||||
|
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '8.0'
|
||||||
|
extensions: ${{ env.extensions }}
|
||||||
|
tools: phpstan
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- name: Cache composer dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
# Use composer.json for key, if composer.lock is not committed.
|
||||||
|
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Static Analysis using PHPStan
|
||||||
|
run: phpstan analyse --no-progress src tests
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,5 +5,5 @@
|
|||||||
/tests/coverage
|
/tests/coverage
|
||||||
/vendor
|
/vendor
|
||||||
/composer.lock
|
/composer.lock
|
||||||
/.php_cs.cache
|
/.php-cs-fixer.cache
|
||||||
/.phpunit.result.cache
|
/.phpunit.result.cache
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$config = PhpCsFixer\Config::create()
|
$finder = PhpCsFixer\Finder::create()
|
||||||
|
->in(__DIR__)
|
||||||
|
->name('*.php')
|
||||||
|
->exclude('vendor');
|
||||||
|
|
||||||
|
$config = new PhpCsFixer\Config();
|
||||||
|
return $config
|
||||||
->setRiskyAllowed(true)
|
->setRiskyAllowed(true)
|
||||||
->setRules([
|
->setRules([
|
||||||
'@Symfony' => true,
|
'@Symfony' => true,
|
||||||
@ -13,13 +19,13 @@ $config = PhpCsFixer\Config::create()
|
|||||||
'declare_equal_normalize' => ['space' => 'single'],
|
'declare_equal_normalize' => ['space' => 'single'],
|
||||||
'heredoc_to_nowdoc' => true,
|
'heredoc_to_nowdoc' => true,
|
||||||
'increment_style' => ['style' => 'post'],
|
'increment_style' => ['style' => 'post'],
|
||||||
'is_null' => ['use_yoda_style' => false],
|
'is_null' => true,
|
||||||
'method_argument_space' => ['ensure_fully_multiline' => true],
|
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
|
||||||
'modernize_types_casting' => true,
|
'modernize_types_casting' => true,
|
||||||
'no_break_comment' => ['comment_text' => 'do nothing'],
|
'no_break_comment' => ['comment_text' => 'do nothing'],
|
||||||
'no_empty_phpdoc' => false,
|
'no_empty_phpdoc' => false,
|
||||||
'no_null_property_initialization' => true,
|
'no_null_property_initialization' => true,
|
||||||
'no_short_echo_tag' => true,
|
'echo_tag_syntax' => false,
|
||||||
'no_superfluous_elseif' => true,
|
'no_superfluous_elseif' => true,
|
||||||
'no_superfluous_phpdoc_tags' => false,
|
'no_superfluous_phpdoc_tags' => false,
|
||||||
'no_unneeded_control_parentheses' => ['statements' => ['break', 'clone', 'continue', 'echo_print', 'switch_case', 'yield']],
|
'no_unneeded_control_parentheses' => ['statements' => ['break', 'clone', 'continue', 'echo_print', 'switch_case', 'yield']],
|
||||||
@ -37,23 +43,12 @@ $config = PhpCsFixer\Config::create()
|
|||||||
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
|
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
|
||||||
'phpdoc_separation' => false,
|
'phpdoc_separation' => false,
|
||||||
'protected_to_private' => true,
|
'protected_to_private' => true,
|
||||||
'psr4' => true,
|
'psr_autoloading' => true,
|
||||||
'return_type_declaration' => ['space_before' => 'one'],
|
'return_type_declaration' => ['space_before' => 'one'],
|
||||||
'semicolon_after_instruction' => true,
|
'semicolon_after_instruction' => true,
|
||||||
'simplified_null_return' => false,
|
'simplified_null_return' => false,
|
||||||
'single_line_comment_style' => ['comment_types' => ['hash']],
|
'single_line_comment_style' => ['comment_types' => ['hash']],
|
||||||
'strict_comparison' => true,
|
'strict_comparison' => true,
|
||||||
'yoda_style' => ['equal' => false, 'identical' => false],
|
'yoda_style' => ['equal' => false, 'identical' => false],
|
||||||
]);
|
])
|
||||||
|
->setFinder($finder);
|
||||||
$config->setFinder(
|
|
||||||
PhpCsFixer\Finder::create()
|
|
||||||
->exclude('vendor')
|
|
||||||
->in(__DIR__)
|
|
||||||
->name('*.php')
|
|
||||||
);
|
|
||||||
|
|
||||||
$cacheDir = getenv('TRAVIS') ? getenv('HOME') . '/.php-cs-fixer' : __DIR__;
|
|
||||||
$config->setCacheFile($cacheDir . '/.php_cs.cache');
|
|
||||||
|
|
||||||
return $config;
|
|
@ -1,57 +0,0 @@
|
|||||||
filter:
|
|
||||||
excluded_paths: [vendor/*, tests/*]
|
|
||||||
|
|
||||||
tools:
|
|
||||||
external_code_coverage:
|
|
||||||
timeout: 600 # Wait 10 minutes for results
|
|
||||||
runs: 1 # Merge results for the 7.1 job
|
|
||||||
php_mess_detector: true
|
|
||||||
php_code_sniffer:
|
|
||||||
config:
|
|
||||||
standard: PSR4
|
|
||||||
filter:
|
|
||||||
paths: ['src']
|
|
||||||
sensiolabs_security_checker: true
|
|
||||||
php_pdepend: true
|
|
||||||
php_loc:
|
|
||||||
enabled: true
|
|
||||||
filter:
|
|
||||||
paths: ['src']
|
|
||||||
php_cpd: false # Must be disabled to use php_sim instead
|
|
||||||
php_sim:
|
|
||||||
enabled: true
|
|
||||||
filter:
|
|
||||||
paths: ['src']
|
|
||||||
|
|
||||||
build_failure_conditions:
|
|
||||||
- 'project.metric("scrutinizer.quality", < 9)' # Code Quality Rating drops below 9
|
|
||||||
- 'project.metric_change("scrutinizer.test_coverage", < -0.005)' # Code Coverage decreased by more than 0.5%
|
|
||||||
- 'project.metric("scrutinizer.test_coverage", < 0.97)' # Code Coverage drops below 97%
|
|
||||||
|
|
||||||
checks:
|
|
||||||
php:
|
|
||||||
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
|
|
||||||
fix_php_opening_tag: true
|
|
||||||
fix_linefeed: true
|
|
||||||
fix_line_ending: true
|
|
||||||
fix_identation_4spaces: true
|
|
||||||
fix_doc_comments: true
|
|
||||||
uppercase_constants: true
|
|
||||||
use_self_instead_of_fqcn: true
|
|
||||||
simplify_boolean_return: true
|
|
||||||
return_doc_comments: true
|
|
||||||
return_doc_comment_if_not_inferrable: true
|
|
||||||
phpunit_assertions: true
|
|
||||||
parameters_in_camelcaps: true
|
|
||||||
parameter_doc_comments: true
|
|
||||||
param_doc_comment_if_not_inferrable: true
|
|
||||||
optional_parameters_at_the_end: true
|
|
||||||
newline_at_end_of_file: true
|
|
||||||
encourage_single_quotes: true
|
|
||||||
|
|
61
.travis.yml
61
.travis.yml
@ -1,61 +0,0 @@
|
|||||||
dist: bionic
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
language: php
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- php: 7.2
|
|
||||||
env: WITH_PHPUNIT=true
|
|
||||||
- php: 7.3
|
|
||||||
env: WITH_PHPUNIT=true
|
|
||||||
- php: 7.3
|
|
||||||
env: WITH_PHPUNIT=true WITH_COVERAGE=true
|
|
||||||
- php: 7.4
|
|
||||||
env: WITH_PHPUNIT=true
|
|
||||||
- php: 8.0
|
|
||||||
env: WITH_PHPUNIT=true
|
|
||||||
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- $HOME/.composer/cache
|
|
||||||
- $HOME/.php-cs-fixer
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- |
|
|
||||||
if [[ "$WITH_COVERAGE" != "true" ]]; then
|
|
||||||
phpenv config-rm xdebug.ini
|
|
||||||
fi
|
|
||||||
if [[ "$WITH_CS" != "true" ]]; then
|
|
||||||
composer remove friendsofphp/php-cs-fixer --dev --no-update
|
|
||||||
fi
|
|
||||||
- composer validate
|
|
||||||
|
|
||||||
install:
|
|
||||||
- composer install --no-interaction --prefer-source
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- mkdir -p "$HOME/.php-cs-fixer"
|
|
||||||
- mkdir -p build/logs
|
|
||||||
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
if [[ "$WITH_CS" == "true" ]]; then
|
|
||||||
vendor/bin/php-cs-fixer fix --config=.php_cs.dist --verbose --diff --dry-run --diff-format=udiff
|
|
||||||
fi
|
|
||||||
- |
|
|
||||||
if [[ "$WITH_PHPUNIT" == "true" ]]; then
|
|
||||||
if [[ "$WITH_COVERAGE" == "true" ]]; then
|
|
||||||
vendor/bin/phpunit --coverage-clover=build/logs/coverage.clover
|
|
||||||
else
|
|
||||||
vendor/bin/phpunit --no-coverage
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
after_script:
|
|
||||||
- |
|
|
||||||
if [[ "$WITH_COVERAGE" == "true" ]]; then
|
|
||||||
wget https://scrutinizer-ci.com/ocular.phar
|
|
||||||
php ocular.phar code-coverage:upload --format=php-clover build/logs/coverage.clover
|
|
||||||
fi
|
|
@ -3,8 +3,7 @@
|
|||||||
[](https://packagist.org/packages/box/spout)
|
[](https://packagist.org/packages/box/spout)
|
||||||
[](https://opensource.box.com/badges)
|
[](https://opensource.box.com/badges)
|
||||||
[](https://travis-ci.org/box/spout)
|
[](https://travis-ci.org/box/spout)
|
||||||
[](https://scrutinizer-ci.com/g/box/spout/?branch=master)
|
[](https://coveralls.io/github/box/spout?branch=master)
|
||||||
[](https://scrutinizer-ci.com/g/box/spout/?branch=master)
|
|
||||||
[](https://packagist.org/packages/box/spout)
|
[](https://packagist.org/packages/box/spout)
|
||||||
|
|
||||||
Spout is a PHP library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way.
|
Spout is a PHP library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way.
|
||||||
|
35
appveyor.yml
35
appveyor.yml
@ -1,35 +0,0 @@
|
|||||||
build: false
|
|
||||||
clone_depth: 1
|
|
||||||
|
|
||||||
environment:
|
|
||||||
PHP_CHOCO_VERSION: 7.2.0
|
|
||||||
PHP_CACHE_DIR: C:\tools\php
|
|
||||||
|
|
||||||
cache:
|
|
||||||
- '%PHP_CACHE_DIR% -> appveyor.yml'
|
|
||||||
|
|
||||||
init:
|
|
||||||
- SET PATH=%PHP_CACHE_DIR%;%PATH%
|
|
||||||
- SET COMPOSER_CACHE_DIR=%PHP_CACHE_DIR%
|
|
||||||
- SET COMPOSER_NO_INTERACTION=1
|
|
||||||
- SET PHP=0
|
|
||||||
- SET ANSICON=121x90 (121x90)
|
|
||||||
|
|
||||||
install:
|
|
||||||
- IF EXIST %PHP_CACHE_DIR% (SET PHP=1)
|
|
||||||
- IF %PHP%==0 cinst php -y --version %PHP_CHOCO_VERSION% --params "/InstallDir:%PHP_CACHE_DIR%"
|
|
||||||
- IF %PHP%==0 cinst composer -y --ia "/DEV=%PHP_CACHE_DIR%"
|
|
||||||
- cd %PHP_CACHE_DIR%
|
|
||||||
- IF %PHP%==0 copy php.ini-production php.ini
|
|
||||||
- IF %PHP%==0 echo extension_dir=ext >> php.ini
|
|
||||||
- IF %PHP%==0 echo extension=php_fileinfo.dll >> php.ini
|
|
||||||
- IF %PHP%==0 echo extension=php_mbstring.dll >> php.ini
|
|
||||||
- IF %PHP%==0 echo extension=php_openssl.dll >> php.ini
|
|
||||||
- php -v
|
|
||||||
- IF %PHP%==0 (composer --version) ELSE (composer self-update)
|
|
||||||
- cd %APPVEYOR_BUILD_FOLDER%
|
|
||||||
- composer install --prefer-dist --no-progress
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- cd %APPVEYOR_BUILD_FOLDER%
|
|
||||||
- vendor\bin\phpunit --colors=always
|
|
@ -12,14 +12,15 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.2.0",
|
"php": ">=7.3.0",
|
||||||
"ext-zip": "*",
|
"ext-zip": "*",
|
||||||
"ext-xmlreader": "*",
|
"ext-xmlreader": "*",
|
||||||
"ext-dom": "*"
|
"ext-dom": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^8",
|
"phpunit/phpunit": "^9",
|
||||||
"friendsofphp/php-cs-fixer": "^2"
|
"friendsofphp/php-cs-fixer": "^3",
|
||||||
|
"phpstan/phpstan": "^1"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-iconv": "To handle non UTF-8 CSV files (if \"php-intl\" is not already installed or is too limited)",
|
"ext-iconv": "To handle non UTF-8 CSV files (if \"php-intl\" is not already installed or is too limited)",
|
||||||
@ -37,7 +38,7 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "7.2"
|
"php": "7.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,38 +13,38 @@ class Cell
|
|||||||
/**
|
/**
|
||||||
* Numeric cell type (whole numbers, fractional numbers, dates)
|
* Numeric cell type (whole numbers, fractional numbers, dates)
|
||||||
*/
|
*/
|
||||||
const TYPE_NUMERIC = 0;
|
public const TYPE_NUMERIC = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String (text) cell type
|
* String (text) cell type
|
||||||
*/
|
*/
|
||||||
const TYPE_STRING = 1;
|
public const TYPE_STRING = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formula cell type
|
* Formula cell type
|
||||||
* Not used at the moment
|
* Not used at the moment
|
||||||
*/
|
*/
|
||||||
const TYPE_FORMULA = 2;
|
public const TYPE_FORMULA = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty cell type
|
* Empty cell type
|
||||||
*/
|
*/
|
||||||
const TYPE_EMPTY = 3;
|
public const TYPE_EMPTY = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boolean cell type
|
* Boolean cell type
|
||||||
*/
|
*/
|
||||||
const TYPE_BOOLEAN = 4;
|
public const TYPE_BOOLEAN = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date cell type
|
* Date cell type
|
||||||
*/
|
*/
|
||||||
const TYPE_DATE = 5;
|
public const TYPE_DATE = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error cell type
|
* Error cell type
|
||||||
*/
|
*/
|
||||||
const TYPE_ERROR = 6;
|
public const TYPE_ERROR = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of this cell
|
* The value of this cell
|
||||||
|
@ -7,20 +7,20 @@ namespace Box\Spout\Common\Entity\Style;
|
|||||||
*/
|
*/
|
||||||
class Border
|
class Border
|
||||||
{
|
{
|
||||||
const LEFT = 'left';
|
public const LEFT = 'left';
|
||||||
const RIGHT = 'right';
|
public const RIGHT = 'right';
|
||||||
const TOP = 'top';
|
public const TOP = 'top';
|
||||||
const BOTTOM = 'bottom';
|
public const BOTTOM = 'bottom';
|
||||||
|
|
||||||
const STYLE_NONE = 'none';
|
public const STYLE_NONE = 'none';
|
||||||
const STYLE_SOLID = 'solid';
|
public const STYLE_SOLID = 'solid';
|
||||||
const STYLE_DASHED = 'dashed';
|
public const STYLE_DASHED = 'dashed';
|
||||||
const STYLE_DOTTED = 'dotted';
|
public const STYLE_DOTTED = 'dotted';
|
||||||
const STYLE_DOUBLE = 'double';
|
public const STYLE_DOUBLE = 'double';
|
||||||
|
|
||||||
const WIDTH_THIN = 'thin';
|
public const WIDTH_THIN = 'thin';
|
||||||
const WIDTH_MEDIUM = 'medium';
|
public const WIDTH_MEDIUM = 'medium';
|
||||||
const WIDTH_THICK = 'thick';
|
public const WIDTH_THICK = 'thick';
|
||||||
|
|
||||||
/** @var array A list of BorderPart objects for this border. */
|
/** @var array A list of BorderPart objects for this border. */
|
||||||
private $parts = [];
|
private $parts = [];
|
||||||
|
@ -8,10 +8,10 @@ namespace Box\Spout\Common\Entity\Style;
|
|||||||
*/
|
*/
|
||||||
abstract class CellAlignment
|
abstract class CellAlignment
|
||||||
{
|
{
|
||||||
const LEFT = 'left';
|
public const LEFT = 'left';
|
||||||
const RIGHT = 'right';
|
public const RIGHT = 'right';
|
||||||
const CENTER = 'center';
|
public const CENTER = 'center';
|
||||||
const JUSTIFY = 'justify';
|
public const JUSTIFY = 'justify';
|
||||||
|
|
||||||
private static $VALID_ALIGNMENTS = [
|
private static $VALID_ALIGNMENTS = [
|
||||||
self::LEFT => 1,
|
self::LEFT => 1,
|
||||||
|
@ -11,18 +11,18 @@ use Box\Spout\Common\Exception\InvalidColorException;
|
|||||||
abstract class Color
|
abstract class Color
|
||||||
{
|
{
|
||||||
/** Standard colors - based on Office Online */
|
/** Standard colors - based on Office Online */
|
||||||
const BLACK = '000000';
|
public const BLACK = '000000';
|
||||||
const WHITE = 'FFFFFF';
|
public const WHITE = 'FFFFFF';
|
||||||
const RED = 'FF0000';
|
public const RED = 'FF0000';
|
||||||
const DARK_RED = 'C00000';
|
public const DARK_RED = 'C00000';
|
||||||
const ORANGE = 'FFC000';
|
public const ORANGE = 'FFC000';
|
||||||
const YELLOW = 'FFFF00';
|
public const YELLOW = 'FFFF00';
|
||||||
const LIGHT_GREEN = '92D040';
|
public const LIGHT_GREEN = '92D040';
|
||||||
const GREEN = '00B050';
|
public const GREEN = '00B050';
|
||||||
const LIGHT_BLUE = '00B0E0';
|
public const LIGHT_BLUE = '00B0E0';
|
||||||
const BLUE = '0070C0';
|
public const BLUE = '0070C0';
|
||||||
const DARK_BLUE = '002060';
|
public const DARK_BLUE = '002060';
|
||||||
const PURPLE = '7030A0';
|
public const PURPLE = '7030A0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an RGB color from R, G and B values
|
* Returns an RGB color from R, G and B values
|
||||||
|
@ -9,9 +9,9 @@ namespace Box\Spout\Common\Entity\Style;
|
|||||||
class Style
|
class Style
|
||||||
{
|
{
|
||||||
/** Default values */
|
/** Default values */
|
||||||
const DEFAULT_FONT_SIZE = 11;
|
public const DEFAULT_FONT_SIZE = 11;
|
||||||
const DEFAULT_FONT_COLOR = Color::BLACK;
|
public const DEFAULT_FONT_COLOR = Color::BLACK;
|
||||||
const DEFAULT_FONT_NAME = 'Arial';
|
public const DEFAULT_FONT_NAME = 'Arial';
|
||||||
|
|
||||||
/** @var int|null Style ID */
|
/** @var int|null Style ID */
|
||||||
private $id;
|
private $id;
|
||||||
|
@ -11,18 +11,18 @@ use Box\Spout\Common\Exception\EncodingConversionException;
|
|||||||
class EncodingHelper
|
class EncodingHelper
|
||||||
{
|
{
|
||||||
/** Definition of the encodings that can have a BOM */
|
/** Definition of the encodings that can have a BOM */
|
||||||
const ENCODING_UTF8 = 'UTF-8';
|
public const ENCODING_UTF8 = 'UTF-8';
|
||||||
const ENCODING_UTF16_LE = 'UTF-16LE';
|
public const ENCODING_UTF16_LE = 'UTF-16LE';
|
||||||
const ENCODING_UTF16_BE = 'UTF-16BE';
|
public const ENCODING_UTF16_BE = 'UTF-16BE';
|
||||||
const ENCODING_UTF32_LE = 'UTF-32LE';
|
public const ENCODING_UTF32_LE = 'UTF-32LE';
|
||||||
const ENCODING_UTF32_BE = 'UTF-32BE';
|
public const ENCODING_UTF32_BE = 'UTF-32BE';
|
||||||
|
|
||||||
/** Definition of the BOMs for the different encodings */
|
/** Definition of the BOMs for the different encodings */
|
||||||
const BOM_UTF8 = "\xEF\xBB\xBF";
|
public const BOM_UTF8 = "\xEF\xBB\xBF";
|
||||||
const BOM_UTF16_LE = "\xFF\xFE";
|
public const BOM_UTF16_LE = "\xFF\xFE";
|
||||||
const BOM_UTF16_BE = "\xFE\xFF";
|
public const BOM_UTF16_BE = "\xFE\xFF";
|
||||||
const BOM_UTF32_LE = "\xFF\xFE\x00\x00";
|
public const BOM_UTF32_LE = "\xFF\xFE\x00\x00";
|
||||||
const BOM_UTF32_BE = "\x00\x00\xFE\xFF";
|
public const BOM_UTF32_BE = "\x00\x00\xFE\xFF";
|
||||||
|
|
||||||
/** @var \Box\Spout\Common\Helper\GlobalFunctionsHelper Helper to work with global functions */
|
/** @var \Box\Spout\Common\Helper\GlobalFunctionsHelper Helper to work with global functions */
|
||||||
protected $globalFunctionsHelper;
|
protected $globalFunctionsHelper;
|
||||||
|
@ -7,7 +7,7 @@ namespace Box\Spout\Common\Manager;
|
|||||||
*/
|
*/
|
||||||
abstract class OptionsManagerAbstract implements OptionsManagerInterface
|
abstract class OptionsManagerAbstract implements OptionsManagerInterface
|
||||||
{
|
{
|
||||||
const PREFIX_OPTION = 'OPTION_';
|
public const PREFIX_OPTION = 'OPTION_';
|
||||||
|
|
||||||
/** @var string[] List of all supported option names */
|
/** @var string[] List of all supported option names */
|
||||||
private $supportedOptions = [];
|
private $supportedOptions = [];
|
||||||
|
@ -8,7 +8,7 @@ namespace Box\Spout\Common;
|
|||||||
*/
|
*/
|
||||||
abstract class Type
|
abstract class Type
|
||||||
{
|
{
|
||||||
const CSV = 'csv';
|
public const CSV = 'csv';
|
||||||
const XLSX = 'xlsx';
|
public const XLSX = 'xlsx';
|
||||||
const ODS = 'ods';
|
public const ODS = 'ods';
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class RowIterator implements RowIteratorInterface
|
|||||||
/**
|
/**
|
||||||
* Value passed to fgetcsv. 0 means "unlimited" (slightly slower but accomodates for very long lines).
|
* Value passed to fgetcsv. 0 means "unlimited" (slightly slower but accomodates for very long lines).
|
||||||
*/
|
*/
|
||||||
const MAX_READ_BYTES_PER_LINE = 0;
|
public const MAX_READ_BYTES_PER_LINE = 0;
|
||||||
|
|
||||||
/** @var resource Pointer to the CSV file to read */
|
/** @var resource Pointer to the CSV file to read */
|
||||||
protected $filePointer;
|
protected $filePointer;
|
||||||
|
@ -35,6 +35,7 @@ class ReaderEntityFactory
|
|||||||
return ReaderFactory::createFromType(Type::CSV);
|
return ReaderFactory::createFromType(Type::CSV);
|
||||||
} catch (UnsupportedTypeException $e) {
|
} catch (UnsupportedTypeException $e) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ class ReaderEntityFactory
|
|||||||
return ReaderFactory::createFromType(Type::XLSX);
|
return ReaderFactory::createFromType(Type::XLSX);
|
||||||
} catch (UnsupportedTypeException $e) {
|
} catch (UnsupportedTypeException $e) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ class ReaderEntityFactory
|
|||||||
return ReaderFactory::createFromType(Type::ODS);
|
return ReaderFactory::createFromType(Type::ODS);
|
||||||
} catch (UnsupportedTypeException $e) {
|
} catch (UnsupportedTypeException $e) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,15 @@ namespace Box\Spout\Reader\Common\Entity;
|
|||||||
abstract class Options
|
abstract class Options
|
||||||
{
|
{
|
||||||
// Common options
|
// Common options
|
||||||
const SHOULD_FORMAT_DATES = 'shouldFormatDates';
|
public const SHOULD_FORMAT_DATES = 'shouldFormatDates';
|
||||||
const SHOULD_PRESERVE_EMPTY_ROWS = 'shouldPreserveEmptyRows';
|
public const SHOULD_PRESERVE_EMPTY_ROWS = 'shouldPreserveEmptyRows';
|
||||||
|
|
||||||
// CSV specific options
|
// CSV specific options
|
||||||
const FIELD_DELIMITER = 'fieldDelimiter';
|
public const FIELD_DELIMITER = 'fieldDelimiter';
|
||||||
const FIELD_ENCLOSURE = 'fieldEnclosure';
|
public const FIELD_ENCLOSURE = 'fieldEnclosure';
|
||||||
const ENCODING = 'encoding';
|
public const ENCODING = 'encoding';
|
||||||
|
|
||||||
// XLSX specific options
|
// XLSX specific options
|
||||||
const TEMP_FOLDER = 'tempFolder';
|
public const TEMP_FOLDER = 'tempFolder';
|
||||||
const SHOULD_USE_1904_DATES = 'shouldUse1904Dates';
|
public const SHOULD_USE_1904_DATES = 'shouldUse1904Dates';
|
||||||
}
|
}
|
||||||
|
@ -11,16 +11,16 @@ use Box\Spout\Reader\Wrapper\XMLReader;
|
|||||||
class XMLProcessor
|
class XMLProcessor
|
||||||
{
|
{
|
||||||
/* Node types */
|
/* Node types */
|
||||||
const NODE_TYPE_START = XMLReader::ELEMENT;
|
public const NODE_TYPE_START = XMLReader::ELEMENT;
|
||||||
const NODE_TYPE_END = XMLReader::END_ELEMENT;
|
public const NODE_TYPE_END = XMLReader::END_ELEMENT;
|
||||||
|
|
||||||
/* Keys associated to reflection attributes to invoke a callback */
|
/* Keys associated to reflection attributes to invoke a callback */
|
||||||
const CALLBACK_REFLECTION_METHOD = 'reflectionMethod';
|
public const CALLBACK_REFLECTION_METHOD = 'reflectionMethod';
|
||||||
const CALLBACK_REFLECTION_OBJECT = 'reflectionObject';
|
public const CALLBACK_REFLECTION_OBJECT = 'reflectionObject';
|
||||||
|
|
||||||
/* Values returned by the callbacks to indicate what the processor should do next */
|
/* Values returned by the callbacks to indicate what the processor should do next */
|
||||||
const PROCESSING_CONTINUE = 1;
|
public const PROCESSING_CONTINUE = 1;
|
||||||
const PROCESSING_STOP = 2;
|
public const PROCESSING_STOP = 2;
|
||||||
|
|
||||||
/** @var \Box\Spout\Reader\Wrapper\XMLReader The XMLReader object that will help read sheet's XML data */
|
/** @var \Box\Spout\Reader\Wrapper\XMLReader The XMLReader object that will help read sheet's XML data */
|
||||||
protected $xmlReader;
|
protected $xmlReader;
|
||||||
|
@ -11,31 +11,31 @@ use Box\Spout\Reader\Exception\InvalidValueException;
|
|||||||
class CellValueFormatter
|
class CellValueFormatter
|
||||||
{
|
{
|
||||||
/** Definition of all possible cell types */
|
/** Definition of all possible cell types */
|
||||||
const CELL_TYPE_STRING = 'string';
|
public const CELL_TYPE_STRING = 'string';
|
||||||
const CELL_TYPE_FLOAT = 'float';
|
public const CELL_TYPE_FLOAT = 'float';
|
||||||
const CELL_TYPE_BOOLEAN = 'boolean';
|
public const CELL_TYPE_BOOLEAN = 'boolean';
|
||||||
const CELL_TYPE_DATE = 'date';
|
public const CELL_TYPE_DATE = 'date';
|
||||||
const CELL_TYPE_TIME = 'time';
|
public const CELL_TYPE_TIME = 'time';
|
||||||
const CELL_TYPE_CURRENCY = 'currency';
|
public const CELL_TYPE_CURRENCY = 'currency';
|
||||||
const CELL_TYPE_PERCENTAGE = 'percentage';
|
public const CELL_TYPE_PERCENTAGE = 'percentage';
|
||||||
const CELL_TYPE_VOID = 'void';
|
public const CELL_TYPE_VOID = 'void';
|
||||||
|
|
||||||
/** Definition of XML nodes names used to parse data */
|
/** Definition of XML nodes names used to parse data */
|
||||||
const XML_NODE_P = 'p';
|
public const XML_NODE_P = 'p';
|
||||||
const XML_NODE_TEXT_A = 'text:a';
|
public const XML_NODE_TEXT_A = 'text:a';
|
||||||
const XML_NODE_TEXT_SPAN = 'text:span';
|
public const XML_NODE_TEXT_SPAN = 'text:span';
|
||||||
const XML_NODE_TEXT_S = 'text:s';
|
public const XML_NODE_TEXT_S = 'text:s';
|
||||||
const XML_NODE_TEXT_TAB = 'text:tab';
|
public const XML_NODE_TEXT_TAB = 'text:tab';
|
||||||
const XML_NODE_TEXT_LINE_BREAK = 'text:line-break';
|
public const XML_NODE_TEXT_LINE_BREAK = 'text:line-break';
|
||||||
|
|
||||||
/** Definition of XML attributes used to parse data */
|
/** Definition of XML attributes used to parse data */
|
||||||
const XML_ATTRIBUTE_TYPE = 'office:value-type';
|
public const XML_ATTRIBUTE_TYPE = 'office:value-type';
|
||||||
const XML_ATTRIBUTE_VALUE = 'office:value';
|
public const XML_ATTRIBUTE_VALUE = 'office:value';
|
||||||
const XML_ATTRIBUTE_BOOLEAN_VALUE = 'office:boolean-value';
|
public const XML_ATTRIBUTE_BOOLEAN_VALUE = 'office:boolean-value';
|
||||||
const XML_ATTRIBUTE_DATE_VALUE = 'office:date-value';
|
public const XML_ATTRIBUTE_DATE_VALUE = 'office:date-value';
|
||||||
const XML_ATTRIBUTE_TIME_VALUE = 'office:time-value';
|
public const XML_ATTRIBUTE_TIME_VALUE = 'office:time-value';
|
||||||
const XML_ATTRIBUTE_CURRENCY = 'office:currency';
|
public const XML_ATTRIBUTE_CURRENCY = 'office:currency';
|
||||||
const XML_ATTRIBUTE_C = 'text:c';
|
public const XML_ATTRIBUTE_C = 'text:c';
|
||||||
|
|
||||||
/** @var bool Whether date/time values should be returned as PHP objects or be formatted as strings */
|
/** @var bool Whether date/time values should be returned as PHP objects or be formatted as strings */
|
||||||
protected $shouldFormatDates;
|
protected $shouldFormatDates;
|
||||||
|
@ -11,12 +11,12 @@ use Box\Spout\Reader\ODS\Creator\InternalEntityFactory;
|
|||||||
*/
|
*/
|
||||||
class SettingsHelper
|
class SettingsHelper
|
||||||
{
|
{
|
||||||
const SETTINGS_XML_FILE_PATH = 'settings.xml';
|
public const SETTINGS_XML_FILE_PATH = 'settings.xml';
|
||||||
|
|
||||||
/** Definition of XML nodes name and attribute used to parse settings data */
|
/** Definition of XML nodes name and attribute used to parse settings data */
|
||||||
const XML_NODE_CONFIG_ITEM = 'config:config-item';
|
public const XML_NODE_CONFIG_ITEM = 'config:config-item';
|
||||||
const XML_ATTRIBUTE_CONFIG_NAME = 'config:name';
|
public const XML_ATTRIBUTE_CONFIG_NAME = 'config:name';
|
||||||
const XML_ATTRIBUTE_VALUE_ACTIVE_TABLE = 'ActiveTable';
|
public const XML_ATTRIBUTE_VALUE_ACTIVE_TABLE = 'ActiveTable';
|
||||||
|
|
||||||
/** @var InternalEntityFactory Factory to create entities */
|
/** @var InternalEntityFactory Factory to create entities */
|
||||||
private $entityFactory;
|
private $entityFactory;
|
||||||
|
@ -23,14 +23,14 @@ use Box\Spout\Reader\Wrapper\XMLReader;
|
|||||||
class RowIterator implements IteratorInterface
|
class RowIterator implements IteratorInterface
|
||||||
{
|
{
|
||||||
/** Definition of XML nodes names used to parse data */
|
/** Definition of XML nodes names used to parse data */
|
||||||
const XML_NODE_TABLE = 'table:table';
|
public const XML_NODE_TABLE = 'table:table';
|
||||||
const XML_NODE_ROW = 'table:table-row';
|
public const XML_NODE_ROW = 'table:table-row';
|
||||||
const XML_NODE_CELL = 'table:table-cell';
|
public const XML_NODE_CELL = 'table:table-cell';
|
||||||
const MAX_COLUMNS_EXCEL = 16384;
|
public const MAX_COLUMNS_EXCEL = 16384;
|
||||||
|
|
||||||
/** Definition of XML attribute used to parse data */
|
/** Definition of XML attribute used to parse data */
|
||||||
const XML_ATTRIBUTE_NUM_ROWS_REPEATED = 'table:number-rows-repeated';
|
public const XML_ATTRIBUTE_NUM_ROWS_REPEATED = 'table:number-rows-repeated';
|
||||||
const XML_ATTRIBUTE_NUM_COLUMNS_REPEATED = 'table:number-columns-repeated';
|
public const XML_ATTRIBUTE_NUM_COLUMNS_REPEATED = 'table:number-columns-repeated';
|
||||||
|
|
||||||
/** @var \Box\Spout\Reader\Wrapper\XMLReader The XMLReader object that will help read sheet's XML data */
|
/** @var \Box\Spout\Reader\Wrapper\XMLReader The XMLReader object that will help read sheet's XML data */
|
||||||
protected $xmlReader;
|
protected $xmlReader;
|
||||||
|
@ -15,18 +15,18 @@ use Box\Spout\Reader\Wrapper\XMLReader;
|
|||||||
*/
|
*/
|
||||||
class SheetIterator implements IteratorInterface
|
class SheetIterator implements IteratorInterface
|
||||||
{
|
{
|
||||||
const CONTENT_XML_FILE_PATH = 'content.xml';
|
public const CONTENT_XML_FILE_PATH = 'content.xml';
|
||||||
|
|
||||||
const XML_STYLE_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:style:1.0';
|
public const XML_STYLE_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:style:1.0';
|
||||||
|
|
||||||
/** Definition of XML nodes name and attribute used to parse sheet data */
|
/** Definition of XML nodes name and attribute used to parse sheet data */
|
||||||
const XML_NODE_AUTOMATIC_STYLES = 'office:automatic-styles';
|
public const XML_NODE_AUTOMATIC_STYLES = 'office:automatic-styles';
|
||||||
const XML_NODE_STYLE_TABLE_PROPERTIES = 'table-properties';
|
public const XML_NODE_STYLE_TABLE_PROPERTIES = 'table-properties';
|
||||||
const XML_NODE_TABLE = 'table:table';
|
public const XML_NODE_TABLE = 'table:table';
|
||||||
const XML_ATTRIBUTE_STYLE_NAME = 'style:name';
|
public const XML_ATTRIBUTE_STYLE_NAME = 'style:name';
|
||||||
const XML_ATTRIBUTE_TABLE_NAME = 'table:name';
|
public const XML_ATTRIBUTE_TABLE_NAME = 'table:name';
|
||||||
const XML_ATTRIBUTE_TABLE_STYLE_NAME = 'table:style-name';
|
public const XML_ATTRIBUTE_TABLE_STYLE_NAME = 'table:style-name';
|
||||||
const XML_ATTRIBUTE_TABLE_DISPLAY = 'table:display';
|
public const XML_ATTRIBUTE_TABLE_DISPLAY = 'table:display';
|
||||||
|
|
||||||
/** @var string Path of the file to be read */
|
/** @var string Path of the file to be read */
|
||||||
protected $filePath;
|
protected $filePath;
|
||||||
|
@ -11,7 +11,7 @@ class XMLReader extends \XMLReader
|
|||||||
{
|
{
|
||||||
use XMLInternalErrorsHelper;
|
use XMLInternalErrorsHelper;
|
||||||
|
|
||||||
const ZIP_WRAPPER = 'zip://';
|
public const ZIP_WRAPPER = 'zip://';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the XML Reader to read a file located inside a ZIP file.
|
* Opens the XML Reader to read a file located inside a ZIP file.
|
||||||
|
@ -13,24 +13,24 @@ use Box\Spout\Reader\XLSX\Manager\StyleManager;
|
|||||||
class CellValueFormatter
|
class CellValueFormatter
|
||||||
{
|
{
|
||||||
/** Definition of all possible cell types */
|
/** Definition of all possible cell types */
|
||||||
const CELL_TYPE_INLINE_STRING = 'inlineStr';
|
public const CELL_TYPE_INLINE_STRING = 'inlineStr';
|
||||||
const CELL_TYPE_STR = 'str';
|
public const CELL_TYPE_STR = 'str';
|
||||||
const CELL_TYPE_SHARED_STRING = 's';
|
public const CELL_TYPE_SHARED_STRING = 's';
|
||||||
const CELL_TYPE_BOOLEAN = 'b';
|
public const CELL_TYPE_BOOLEAN = 'b';
|
||||||
const CELL_TYPE_NUMERIC = 'n';
|
public const CELL_TYPE_NUMERIC = 'n';
|
||||||
const CELL_TYPE_DATE = 'd';
|
public const CELL_TYPE_DATE = 'd';
|
||||||
const CELL_TYPE_ERROR = 'e';
|
public const CELL_TYPE_ERROR = 'e';
|
||||||
|
|
||||||
/** Definition of XML nodes names used to parse data */
|
/** Definition of XML nodes names used to parse data */
|
||||||
const XML_NODE_VALUE = 'v';
|
public const XML_NODE_VALUE = 'v';
|
||||||
const XML_NODE_INLINE_STRING_VALUE = 't';
|
public const XML_NODE_INLINE_STRING_VALUE = 't';
|
||||||
|
|
||||||
/** Definition of XML attributes used to parse data */
|
/** Definition of XML attributes used to parse data */
|
||||||
const XML_ATTRIBUTE_TYPE = 't';
|
public const XML_ATTRIBUTE_TYPE = 't';
|
||||||
const XML_ATTRIBUTE_STYLE_ID = 's';
|
public const XML_ATTRIBUTE_STYLE_ID = 's';
|
||||||
|
|
||||||
/** Constants used for date formatting */
|
/** Constants used for date formatting */
|
||||||
const NUM_SECONDS_IN_ONE_DAY = 86400;
|
public const NUM_SECONDS_IN_ONE_DAY = 86400;
|
||||||
|
|
||||||
/** @var SharedStringsManager Manages shared strings */
|
/** @var SharedStringsManager Manages shared strings */
|
||||||
protected $sharedStringsManager;
|
protected $sharedStringsManager;
|
||||||
|
@ -8,9 +8,9 @@ namespace Box\Spout\Reader\XLSX\Helper;
|
|||||||
*/
|
*/
|
||||||
class DateFormatHelper
|
class DateFormatHelper
|
||||||
{
|
{
|
||||||
const KEY_GENERAL = 'general';
|
public const KEY_GENERAL = 'general';
|
||||||
const KEY_HOUR_12 = '12h';
|
public const KEY_HOUR_12 = '12h';
|
||||||
const KEY_HOUR_24 = '24h';
|
public const KEY_HOUR_24 = '24h';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This map is used to replace Excel format characters by their PHP equivalent.
|
* This map is used to replace Excel format characters by their PHP equivalent.
|
||||||
|
@ -37,7 +37,7 @@ class CachingStrategyFactory
|
|||||||
* This means that in order to store one shared string in memory, the memory amount needed is:
|
* This means that in order to store one shared string in memory, the memory amount needed is:
|
||||||
* => 20 * 600 ≈ 12KB
|
* => 20 * 600 ≈ 12KB
|
||||||
*/
|
*/
|
||||||
const AMOUNT_MEMORY_NEEDED_PER_STRING_IN_KB = 12;
|
public const AMOUNT_MEMORY_NEEDED_PER_STRING_IN_KB = 12;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To avoid running out of memory when extracting a huge number of shared strings, they can be saved to temporary files
|
* To avoid running out of memory when extracting a huge number of shared strings, they can be saved to temporary files
|
||||||
@ -48,7 +48,7 @@ class CachingStrategyFactory
|
|||||||
* best when the indexes of the shared strings are sorted in the sheet data.
|
* best when the indexes of the shared strings are sorted in the sheet data.
|
||||||
* 10,000 was chosen because it creates small files that are fast to be loaded in memory.
|
* 10,000 was chosen because it creates small files that are fast to be loaded in memory.
|
||||||
*/
|
*/
|
||||||
const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000;
|
public const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the best caching strategy, given the number of unique shared strings
|
* Returns the best caching strategy, given the number of unique shared strings
|
||||||
|
@ -15,7 +15,7 @@ use Box\Spout\Reader\XLSX\Creator\HelperFactory;
|
|||||||
class FileBasedStrategy implements CachingStrategyInterface
|
class FileBasedStrategy implements CachingStrategyInterface
|
||||||
{
|
{
|
||||||
/** Value to use to escape the line feed character ("\n") */
|
/** Value to use to escape the line feed character ("\n") */
|
||||||
const ESCAPED_LINE_FEED_CHARACTER = '_x000A_';
|
public const ESCAPED_LINE_FEED_CHARACTER = '_x000A_';
|
||||||
|
|
||||||
/** @var \Box\Spout\Common\Helper\GlobalFunctionsHelper Helper to work with global functions */
|
/** @var \Box\Spout\Common\Helper\GlobalFunctionsHelper Helper to work with global functions */
|
||||||
protected $globalFunctionsHelper;
|
protected $globalFunctionsHelper;
|
||||||
|
@ -17,16 +17,16 @@ use Box\Spout\Reader\XLSX\Manager\SharedStringsCaching\CachingStrategyInterface;
|
|||||||
class SharedStringsManager
|
class SharedStringsManager
|
||||||
{
|
{
|
||||||
/** Definition of XML nodes names used to parse data */
|
/** Definition of XML nodes names used to parse data */
|
||||||
const XML_NODE_SST = 'sst';
|
public const XML_NODE_SST = 'sst';
|
||||||
const XML_NODE_SI = 'si';
|
public const XML_NODE_SI = 'si';
|
||||||
const XML_NODE_R = 'r';
|
public const XML_NODE_R = 'r';
|
||||||
const XML_NODE_T = 't';
|
public const XML_NODE_T = 't';
|
||||||
|
|
||||||
/** Definition of XML attributes used to parse data */
|
/** Definition of XML attributes used to parse data */
|
||||||
const XML_ATTRIBUTE_COUNT = 'count';
|
public const XML_ATTRIBUTE_COUNT = 'count';
|
||||||
const XML_ATTRIBUTE_UNIQUE_COUNT = 'uniqueCount';
|
public const XML_ATTRIBUTE_UNIQUE_COUNT = 'uniqueCount';
|
||||||
const XML_ATTRIBUTE_XML_SPACE = 'xml:space';
|
public const XML_ATTRIBUTE_XML_SPACE = 'xml:space';
|
||||||
const XML_ATTRIBUTE_VALUE_PRESERVE = 'preserve';
|
public const XML_ATTRIBUTE_VALUE_PRESERVE = 'preserve';
|
||||||
|
|
||||||
/** @var string Path of the XLSX file being read */
|
/** @var string Path of the XLSX file being read */
|
||||||
protected $filePath;
|
protected $filePath;
|
||||||
|
@ -14,27 +14,27 @@ use Box\Spout\Reader\XLSX\Sheet;
|
|||||||
class SheetManager
|
class SheetManager
|
||||||
{
|
{
|
||||||
/** Paths of XML files relative to the XLSX file root */
|
/** Paths of XML files relative to the XLSX file root */
|
||||||
const WORKBOOK_XML_RELS_FILE_PATH = 'xl/_rels/workbook.xml.rels';
|
public const WORKBOOK_XML_RELS_FILE_PATH = 'xl/_rels/workbook.xml.rels';
|
||||||
const WORKBOOK_XML_FILE_PATH = 'xl/workbook.xml';
|
public const WORKBOOK_XML_FILE_PATH = 'xl/workbook.xml';
|
||||||
|
|
||||||
/** Definition of XML node names used to parse data */
|
/** Definition of XML node names used to parse data */
|
||||||
const XML_NODE_WORKBOOK_PROPERTIES = 'workbookPr';
|
public const XML_NODE_WORKBOOK_PROPERTIES = 'workbookPr';
|
||||||
const XML_NODE_WORKBOOK_VIEW = 'workbookView';
|
public const XML_NODE_WORKBOOK_VIEW = 'workbookView';
|
||||||
const XML_NODE_SHEET = 'sheet';
|
public const XML_NODE_SHEET = 'sheet';
|
||||||
const XML_NODE_SHEETS = 'sheets';
|
public const XML_NODE_SHEETS = 'sheets';
|
||||||
const XML_NODE_RELATIONSHIP = 'Relationship';
|
public const XML_NODE_RELATIONSHIP = 'Relationship';
|
||||||
|
|
||||||
/** Definition of XML attributes used to parse data */
|
/** Definition of XML attributes used to parse data */
|
||||||
const XML_ATTRIBUTE_DATE_1904 = 'date1904';
|
public const XML_ATTRIBUTE_DATE_1904 = 'date1904';
|
||||||
const XML_ATTRIBUTE_ACTIVE_TAB = 'activeTab';
|
public const XML_ATTRIBUTE_ACTIVE_TAB = 'activeTab';
|
||||||
const XML_ATTRIBUTE_R_ID = 'r:id';
|
public const XML_ATTRIBUTE_R_ID = 'r:id';
|
||||||
const XML_ATTRIBUTE_NAME = 'name';
|
public const XML_ATTRIBUTE_NAME = 'name';
|
||||||
const XML_ATTRIBUTE_STATE = 'state';
|
public const XML_ATTRIBUTE_STATE = 'state';
|
||||||
const XML_ATTRIBUTE_ID = 'Id';
|
public const XML_ATTRIBUTE_ID = 'Id';
|
||||||
const XML_ATTRIBUTE_TARGET = 'Target';
|
public const XML_ATTRIBUTE_TARGET = 'Target';
|
||||||
|
|
||||||
/** State value to represent a hidden sheet */
|
/** State value to represent a hidden sheet */
|
||||||
const SHEET_STATE_HIDDEN = 'hidden';
|
public const SHEET_STATE_HIDDEN = 'hidden';
|
||||||
|
|
||||||
/** @var string Path of the XLSX file being read */
|
/** @var string Path of the XLSX file being read */
|
||||||
protected $filePath;
|
protected $filePath;
|
||||||
|
@ -11,20 +11,20 @@ use Box\Spout\Reader\XLSX\Creator\InternalEntityFactory;
|
|||||||
class StyleManager
|
class StyleManager
|
||||||
{
|
{
|
||||||
/** Nodes used to find relevant information in the styles XML file */
|
/** Nodes used to find relevant information in the styles XML file */
|
||||||
const XML_NODE_NUM_FMTS = 'numFmts';
|
public const XML_NODE_NUM_FMTS = 'numFmts';
|
||||||
const XML_NODE_NUM_FMT = 'numFmt';
|
public const XML_NODE_NUM_FMT = 'numFmt';
|
||||||
const XML_NODE_CELL_XFS = 'cellXfs';
|
public const XML_NODE_CELL_XFS = 'cellXfs';
|
||||||
const XML_NODE_XF = 'xf';
|
public const XML_NODE_XF = 'xf';
|
||||||
|
|
||||||
/** Attributes used to find relevant information in the styles XML file */
|
/** Attributes used to find relevant information in the styles XML file */
|
||||||
const XML_ATTRIBUTE_NUM_FMT_ID = 'numFmtId';
|
public const XML_ATTRIBUTE_NUM_FMT_ID = 'numFmtId';
|
||||||
const XML_ATTRIBUTE_FORMAT_CODE = 'formatCode';
|
public const XML_ATTRIBUTE_FORMAT_CODE = 'formatCode';
|
||||||
const XML_ATTRIBUTE_APPLY_NUMBER_FORMAT = 'applyNumberFormat';
|
public const XML_ATTRIBUTE_APPLY_NUMBER_FORMAT = 'applyNumberFormat';
|
||||||
|
|
||||||
/** By convention, default style ID is 0 */
|
/** By convention, default style ID is 0 */
|
||||||
const DEFAULT_STYLE_ID = 0;
|
public const DEFAULT_STYLE_ID = 0;
|
||||||
|
|
||||||
const NUMBER_FORMAT_GENERAL = 'General';
|
public const NUMBER_FORMAT_GENERAL = 'General';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://msdn.microsoft.com/en-us/library/ff529597(v=office.12).aspx
|
* @see https://msdn.microsoft.com/en-us/library/ff529597(v=office.12).aspx
|
||||||
|
@ -12,21 +12,21 @@ use Box\Spout\Reader\XLSX\Creator\InternalEntityFactory;
|
|||||||
*/
|
*/
|
||||||
class WorkbookRelationshipsManager
|
class WorkbookRelationshipsManager
|
||||||
{
|
{
|
||||||
const BASE_PATH = 'xl/';
|
public const BASE_PATH = 'xl/';
|
||||||
|
|
||||||
/** Path of workbook relationships XML file inside the XLSX file */
|
/** Path of workbook relationships XML file inside the XLSX file */
|
||||||
const WORKBOOK_RELS_XML_FILE_PATH = 'xl/_rels/workbook.xml.rels';
|
public const WORKBOOK_RELS_XML_FILE_PATH = 'xl/_rels/workbook.xml.rels';
|
||||||
|
|
||||||
/** Relationships types - For Transitional and Strict OOXML */
|
/** Relationships types - For Transitional and Strict OOXML */
|
||||||
const RELATIONSHIP_TYPE_SHARED_STRINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings';
|
public const RELATIONSHIP_TYPE_SHARED_STRINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings';
|
||||||
const RELATIONSHIP_TYPE_STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles';
|
public const RELATIONSHIP_TYPE_STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles';
|
||||||
const RELATIONSHIP_TYPE_SHARED_STRINGS_STRICT = 'http://purl.oclc.org/ooxml/officeDocument/relationships/sharedStrings';
|
public const RELATIONSHIP_TYPE_SHARED_STRINGS_STRICT = 'http://purl.oclc.org/ooxml/officeDocument/relationships/sharedStrings';
|
||||||
const RELATIONSHIP_TYPE_STYLES_STRICT = 'http://purl.oclc.org/ooxml/officeDocument/relationships/styles';
|
public const RELATIONSHIP_TYPE_STYLES_STRICT = 'http://purl.oclc.org/ooxml/officeDocument/relationships/styles';
|
||||||
|
|
||||||
/** Nodes and attributes used to find relevant information in the workbook relationships XML file */
|
/** Nodes and attributes used to find relevant information in the workbook relationships XML file */
|
||||||
const XML_NODE_RELATIONSHIP = 'Relationship';
|
public const XML_NODE_RELATIONSHIP = 'Relationship';
|
||||||
const XML_ATTRIBUTE_TYPE = 'Type';
|
public const XML_ATTRIBUTE_TYPE = 'Type';
|
||||||
const XML_ATTRIBUTE_TARGET = 'Target';
|
public const XML_ATTRIBUTE_TARGET = 'Target';
|
||||||
|
|
||||||
/** @var string Path of the XLSX file being read */
|
/** @var string Path of the XLSX file being read */
|
||||||
private $filePath;
|
private $filePath;
|
||||||
|
@ -21,16 +21,16 @@ use Box\Spout\Reader\XLSX\Helper\CellValueFormatter;
|
|||||||
class RowIterator implements IteratorInterface
|
class RowIterator implements IteratorInterface
|
||||||
{
|
{
|
||||||
/** Definition of XML nodes names used to parse data */
|
/** Definition of XML nodes names used to parse data */
|
||||||
const XML_NODE_DIMENSION = 'dimension';
|
public const XML_NODE_DIMENSION = 'dimension';
|
||||||
const XML_NODE_WORKSHEET = 'worksheet';
|
public const XML_NODE_WORKSHEET = 'worksheet';
|
||||||
const XML_NODE_ROW = 'row';
|
public const XML_NODE_ROW = 'row';
|
||||||
const XML_NODE_CELL = 'c';
|
public const XML_NODE_CELL = 'c';
|
||||||
|
|
||||||
/** Definition of XML attributes used to parse data */
|
/** Definition of XML attributes used to parse data */
|
||||||
const XML_ATTRIBUTE_REF = 'ref';
|
public const XML_ATTRIBUTE_REF = 'ref';
|
||||||
const XML_ATTRIBUTE_SPANS = 'spans';
|
public const XML_ATTRIBUTE_SPANS = 'spans';
|
||||||
const XML_ATTRIBUTE_ROW_INDEX = 'r';
|
public const XML_ATTRIBUTE_ROW_INDEX = 'r';
|
||||||
const XML_ATTRIBUTE_CELL_INDEX = 'r';
|
public const XML_ATTRIBUTE_CELL_INDEX = 'r';
|
||||||
|
|
||||||
/** @var string Path of the XLSX file being read */
|
/** @var string Path of the XLSX file being read */
|
||||||
protected $filePath;
|
protected $filePath;
|
||||||
|
@ -15,7 +15,7 @@ use Box\Spout\Writer\WriterAbstract;
|
|||||||
class Writer extends WriterAbstract
|
class Writer extends WriterAbstract
|
||||||
{
|
{
|
||||||
/** Number of rows to write before flushing */
|
/** Number of rows to write before flushing */
|
||||||
const FLUSH_THRESHOLD = 500;
|
public const FLUSH_THRESHOLD = 500;
|
||||||
|
|
||||||
/** @var string Content-Type value for the header */
|
/** @var string Content-Type value for the header */
|
||||||
protected static $headerContentType = 'text/csv; charset=UTF-8';
|
protected static $headerContentType = 'text/csv; charset=UTF-8';
|
||||||
|
@ -50,6 +50,7 @@ class WriterEntityFactory
|
|||||||
return WriterFactory::createFromType(Type::CSV);
|
return WriterFactory::createFromType(Type::CSV);
|
||||||
} catch (UnsupportedTypeException $e) {
|
} catch (UnsupportedTypeException $e) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ class WriterEntityFactory
|
|||||||
return WriterFactory::createFromType(Type::XLSX);
|
return WriterFactory::createFromType(Type::XLSX);
|
||||||
} catch (UnsupportedTypeException $e) {
|
} catch (UnsupportedTypeException $e) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +80,7 @@ class WriterEntityFactory
|
|||||||
return WriterFactory::createFromType(Type::ODS);
|
return WriterFactory::createFromType(Type::ODS);
|
||||||
} catch (UnsupportedTypeException $e) {
|
} catch (UnsupportedTypeException $e) {
|
||||||
// should never happen
|
// should never happen
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,15 +9,15 @@ namespace Box\Spout\Writer\Common\Entity;
|
|||||||
abstract class Options
|
abstract class Options
|
||||||
{
|
{
|
||||||
// CSV specific options
|
// CSV specific options
|
||||||
const FIELD_DELIMITER = 'fieldDelimiter';
|
public const FIELD_DELIMITER = 'fieldDelimiter';
|
||||||
const FIELD_ENCLOSURE = 'fieldEnclosure';
|
public const FIELD_ENCLOSURE = 'fieldEnclosure';
|
||||||
const SHOULD_ADD_BOM = 'shouldAddBOM';
|
public const SHOULD_ADD_BOM = 'shouldAddBOM';
|
||||||
|
|
||||||
// Multisheets options
|
// Multisheets options
|
||||||
const TEMP_FOLDER = 'tempFolder';
|
public const TEMP_FOLDER = 'tempFolder';
|
||||||
const DEFAULT_ROW_STYLE = 'defaultRowStyle';
|
public const DEFAULT_ROW_STYLE = 'defaultRowStyle';
|
||||||
const SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY = 'shouldCreateNewSheetsAutomatically';
|
public const SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY = 'shouldCreateNewSheetsAutomatically';
|
||||||
|
|
||||||
// XLSX specific options
|
// XLSX specific options
|
||||||
const SHOULD_USE_INLINE_STRINGS = 'shouldUseInlineStrings';
|
public const SHOULD_USE_INLINE_STRINGS = 'shouldUseInlineStrings';
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use Box\Spout\Writer\Common\Manager\SheetManager;
|
|||||||
*/
|
*/
|
||||||
class Sheet
|
class Sheet
|
||||||
{
|
{
|
||||||
const DEFAULT_SHEET_NAME_PREFIX = 'Sheet';
|
public const DEFAULT_SHEET_NAME_PREFIX = 'Sheet';
|
||||||
|
|
||||||
/** @var int Index of the sheet, based on order in the workbook (zero-based) */
|
/** @var int Index of the sheet, based on order in the workbook (zero-based) */
|
||||||
private $index;
|
private $index;
|
||||||
|
@ -10,11 +10,11 @@ use Box\Spout\Writer\Common\Creator\InternalEntityFactory;
|
|||||||
*/
|
*/
|
||||||
class ZipHelper
|
class ZipHelper
|
||||||
{
|
{
|
||||||
const ZIP_EXTENSION = '.zip';
|
public const ZIP_EXTENSION = '.zip';
|
||||||
|
|
||||||
/** Controls what to do when trying to add an existing file */
|
/** Controls what to do when trying to add an existing file */
|
||||||
const EXISTING_FILES_SKIP = 'skip';
|
public const EXISTING_FILES_SKIP = 'skip';
|
||||||
const EXISTING_FILES_OVERWRITE = 'overwrite';
|
public const EXISTING_FILES_OVERWRITE = 'overwrite';
|
||||||
|
|
||||||
/** @var InternalEntityFactory Factory to create entities */
|
/** @var InternalEntityFactory Factory to create entities */
|
||||||
private $entityFactory;
|
private $entityFactory;
|
||||||
|
@ -13,7 +13,7 @@ use Box\Spout\Writer\Exception\InvalidSheetNameException;
|
|||||||
class SheetManager
|
class SheetManager
|
||||||
{
|
{
|
||||||
/** Sheet name should not exceed 31 characters */
|
/** Sheet name should not exceed 31 characters */
|
||||||
const MAX_LENGTH_SHEET_NAME = 31;
|
public const MAX_LENGTH_SHEET_NAME = 31;
|
||||||
|
|
||||||
/** @var array Invalid characters that cannot be contained in the sheet name */
|
/** @var array Invalid characters that cannot be contained in the sheet name */
|
||||||
private static $INVALID_CHARACTERS_IN_SHEET_NAME = ['\\', '/', '?', '*', ':', '[', ']'];
|
private static $INVALID_CHARACTERS_IN_SHEET_NAME = ['\\', '/', '?', '*', ':', '[', ']'];
|
||||||
|
@ -15,17 +15,17 @@ use Box\Spout\Writer\ODS\Manager\WorksheetManager;
|
|||||||
*/
|
*/
|
||||||
class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper implements FileSystemWithRootFolderHelperInterface
|
class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper implements FileSystemWithRootFolderHelperInterface
|
||||||
{
|
{
|
||||||
const APP_NAME = 'Spout';
|
public const APP_NAME = 'Spout';
|
||||||
const MIMETYPE = 'application/vnd.oasis.opendocument.spreadsheet';
|
public const MIMETYPE = 'application/vnd.oasis.opendocument.spreadsheet';
|
||||||
|
|
||||||
const META_INF_FOLDER_NAME = 'META-INF';
|
public const META_INF_FOLDER_NAME = 'META-INF';
|
||||||
const SHEETS_CONTENT_TEMP_FOLDER_NAME = 'worksheets-temp';
|
public const SHEETS_CONTENT_TEMP_FOLDER_NAME = 'worksheets-temp';
|
||||||
|
|
||||||
const MANIFEST_XML_FILE_NAME = 'manifest.xml';
|
public const MANIFEST_XML_FILE_NAME = 'manifest.xml';
|
||||||
const CONTENT_XML_FILE_NAME = 'content.xml';
|
public const CONTENT_XML_FILE_NAME = 'content.xml';
|
||||||
const META_XML_FILE_NAME = 'meta.xml';
|
public const META_XML_FILE_NAME = 'meta.xml';
|
||||||
const MIMETYPE_FILE_NAME = 'mimetype';
|
public const MIMETYPE_FILE_NAME = 'mimetype';
|
||||||
const STYLES_XML_FILE_NAME = 'styles.xml';
|
public const STYLES_XML_FILE_NAME = 'styles.xml';
|
||||||
|
|
||||||
/** @var ZipHelper Helper to perform tasks with Zip archive */
|
/** @var ZipHelper Helper to perform tasks with Zip archive */
|
||||||
private $zipHelper;
|
private $zipHelper;
|
||||||
|
@ -14,20 +14,20 @@ use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
|
|||||||
*/
|
*/
|
||||||
class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper implements FileSystemWithRootFolderHelperInterface
|
class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper implements FileSystemWithRootFolderHelperInterface
|
||||||
{
|
{
|
||||||
const APP_NAME = 'Spout';
|
public const APP_NAME = 'Spout';
|
||||||
|
|
||||||
const RELS_FOLDER_NAME = '_rels';
|
public const RELS_FOLDER_NAME = '_rels';
|
||||||
const DOC_PROPS_FOLDER_NAME = 'docProps';
|
public const DOC_PROPS_FOLDER_NAME = 'docProps';
|
||||||
const XL_FOLDER_NAME = 'xl';
|
public const XL_FOLDER_NAME = 'xl';
|
||||||
const WORKSHEETS_FOLDER_NAME = 'worksheets';
|
public const WORKSHEETS_FOLDER_NAME = 'worksheets';
|
||||||
|
|
||||||
const RELS_FILE_NAME = '.rels';
|
public const RELS_FILE_NAME = '.rels';
|
||||||
const APP_XML_FILE_NAME = 'app.xml';
|
public const APP_XML_FILE_NAME = 'app.xml';
|
||||||
const CORE_XML_FILE_NAME = 'core.xml';
|
public const CORE_XML_FILE_NAME = 'core.xml';
|
||||||
const CONTENT_TYPES_XML_FILE_NAME = '[Content_Types].xml';
|
public const CONTENT_TYPES_XML_FILE_NAME = '[Content_Types].xml';
|
||||||
const WORKBOOK_XML_FILE_NAME = 'workbook.xml';
|
public const WORKBOOK_XML_FILE_NAME = 'workbook.xml';
|
||||||
const WORKBOOK_RELS_XML_FILE_NAME = 'workbook.xml.rels';
|
public const WORKBOOK_RELS_XML_FILE_NAME = 'workbook.xml.rels';
|
||||||
const STYLES_XML_FILE_NAME = 'styles.xml';
|
public const STYLES_XML_FILE_NAME = 'styles.xml';
|
||||||
|
|
||||||
/** @var ZipHelper Helper to perform tasks with Zip archive */
|
/** @var ZipHelper Helper to perform tasks with Zip archive */
|
||||||
private $zipHelper;
|
private $zipHelper;
|
||||||
|
@ -13,8 +13,8 @@ use Box\Spout\Writer\Common\Entity\Options;
|
|||||||
class OptionsManager extends OptionsManagerAbstract
|
class OptionsManager extends OptionsManagerAbstract
|
||||||
{
|
{
|
||||||
/** Default style font values */
|
/** Default style font values */
|
||||||
const DEFAULT_FONT_SIZE = 12;
|
public const DEFAULT_FONT_SIZE = 12;
|
||||||
const DEFAULT_FONT_NAME = 'Calibri';
|
public const DEFAULT_FONT_NAME = 'Calibri';
|
||||||
|
|
||||||
/** @var StyleBuilder Style builder */
|
/** @var StyleBuilder Style builder */
|
||||||
protected $styleBuilder;
|
protected $styleBuilder;
|
||||||
|
@ -11,9 +11,9 @@ use Box\Spout\Common\Helper\Escaper;
|
|||||||
*/
|
*/
|
||||||
class SharedStringsManager
|
class SharedStringsManager
|
||||||
{
|
{
|
||||||
const SHARED_STRINGS_FILE_NAME = 'sharedStrings.xml';
|
public const SHARED_STRINGS_FILE_NAME = 'sharedStrings.xml';
|
||||||
|
|
||||||
const SHARED_STRINGS_XML_FILE_FIRST_PART_HEADER = <<<'EOD'
|
public const SHARED_STRINGS_XML_FILE_FIRST_PART_HEADER = <<<'EOD'
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||||
EOD;
|
EOD;
|
||||||
@ -22,7 +22,7 @@ EOD;
|
|||||||
* This number must be really big so that the no generated file will have more strings than that.
|
* This number must be really big so that the no generated file will have more strings than that.
|
||||||
* If the strings number goes above, characters will be overwritten in an unwanted way and will corrupt the file.
|
* If the strings number goes above, characters will be overwritten in an unwanted way and will corrupt the file.
|
||||||
*/
|
*/
|
||||||
const DEFAULT_STRINGS_COUNT_PART = 'count="9999999999999" uniqueCount="9999999999999"';
|
public const DEFAULT_STRINGS_COUNT_PART = 'count="9999999999999" uniqueCount="9999999999999"';
|
||||||
|
|
||||||
/** @var resource Pointer to the sharedStrings.xml file */
|
/** @var resource Pointer to the sharedStrings.xml file */
|
||||||
protected $sharedStringsFilePointer;
|
protected $sharedStringsFilePointer;
|
||||||
|
@ -32,9 +32,9 @@ class WorksheetManager implements WorksheetManagerInterface
|
|||||||
* @see https://support.office.com/en-us/article/Excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 [Excel 2010]
|
* @see https://support.office.com/en-us/article/Excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 [Excel 2010]
|
||||||
* @see https://support.office.com/en-us/article/Excel-specifications-and-limits-ca36e2dc-1f09-4620-b726-67c00b05040f [Excel 2013/2016]
|
* @see https://support.office.com/en-us/article/Excel-specifications-and-limits-ca36e2dc-1f09-4620-b726-67c00b05040f [Excel 2013/2016]
|
||||||
*/
|
*/
|
||||||
const MAX_CHARACTERS_PER_CELL = 32767;
|
public const MAX_CHARACTERS_PER_CELL = 32767;
|
||||||
|
|
||||||
const SHEET_XML_FILE_HEADER = <<<'EOD'
|
public const SHEET_XML_FILE_HEADER = <<<'EOD'
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
||||||
EOD;
|
EOD;
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
class CellTypeHelperTest extends TestCase
|
class CellTypeHelperTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testIsEmpty()
|
public function testIsEmpty()
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ class CellTypeHelperTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testIsNonEmptyString()
|
public function testIsNonEmptyString()
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ class CellTypeHelperTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testIsNumeric()
|
public function testIsNumeric()
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ class CellTypeHelperTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testIsBoolean()
|
public function testIsBoolean()
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,9 @@ class ReaderTest extends TestCase
|
|||||||
public function testReadShouldNotTruncateLineBreak()
|
public function testReadShouldNotTruncateLineBreak()
|
||||||
{
|
{
|
||||||
$allRows = $this->getAllRowsForFile('csv_with_line_breaks.csv');
|
$allRows = $this->getAllRowsForFile('csv_with_line_breaks.csv');
|
||||||
$this->assertEquals("This is,\na comma", $allRows[0][0]);
|
|
||||||
|
$newLine = PHP_EOL; // to support both Unix and Windows
|
||||||
|
$this->assertEquals("This is,{$newLine}a comma", $allRows[0][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -419,10 +421,11 @@ class ReaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$allRows = $this->getAllRowsForFile('sheet_with_untrimmed_strings.csv');
|
$allRows = $this->getAllRowsForFile('sheet_with_untrimmed_strings.csv');
|
||||||
|
|
||||||
|
$newLine = PHP_EOL; // to support both Unix and Windows
|
||||||
$expectedRows = [
|
$expectedRows = [
|
||||||
['A'],
|
['A'],
|
||||||
[' A '],
|
[' A '],
|
||||||
["\n\tA\n\t"],
|
["$newLine\tA$newLine\t"],
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertEquals($expectedRows, $allRows, 'Cell values should not be trimmed');
|
$this->assertEquals($expectedRows, $allRows, 'Cell values should not be trimmed');
|
||||||
|
@ -9,10 +9,10 @@ namespace Box\Spout\Reader\CSV;
|
|||||||
*/
|
*/
|
||||||
class SpoutTestStream
|
class SpoutTestStream
|
||||||
{
|
{
|
||||||
const CLASS_NAME = __CLASS__;
|
public const CLASS_NAME = __CLASS__;
|
||||||
|
|
||||||
const PATH_TO_CSV_RESOURCES = 'tests/resources/csv/';
|
public const PATH_TO_CSV_RESOURCES = 'tests/resources/csv/';
|
||||||
const CSV_EXTENSION = '.csv';
|
public const CSV_EXTENSION = '.csv';
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private $position;
|
private $position;
|
||||||
|
@ -46,7 +46,7 @@ class CachingStrategyFactoryTest extends TestCase
|
|||||||
$factoryStub->method('getMemoryLimitInKB')->willReturn($memoryLimitInKB);
|
$factoryStub->method('getMemoryLimitInKB')->willReturn($memoryLimitInKB);
|
||||||
|
|
||||||
$tempFolder = sys_get_temp_dir();
|
$tempFolder = sys_get_temp_dir();
|
||||||
$helperFactory = new HelperFactory($factoryStub);
|
$helperFactory = new HelperFactory();
|
||||||
$strategy = $factoryStub->createBestCachingStrategy($sharedStringsUniqueCount, $tempFolder, $helperFactory);
|
$strategy = $factoryStub->createBestCachingStrategy($sharedStringsUniqueCount, $tempFolder, $helperFactory);
|
||||||
|
|
||||||
$fullExpectedStrategyClassName = 'Box\Spout\Reader\XLSX\Manager\SharedStringsCaching\\' . $expectedStrategyClassName;
|
$fullExpectedStrategyClassName = 'Box\Spout\Reader\XLSX\Manager\SharedStringsCaching\\' . $expectedStrategyClassName;
|
||||||
|
@ -62,7 +62,7 @@ class ReflectionHelper
|
|||||||
|
|
||||||
// to prevent side-effects in later tests, we need to remember the original value and reset it on tear down
|
// to prevent side-effects in later tests, we need to remember the original value and reset it on tear down
|
||||||
// @NOTE: we need to check isset in case the original value was null or array()
|
// @NOTE: we need to check isset in case the original value was null or array()
|
||||||
if ($saveOriginalValue && (!isset(self::$privateVarsToReset[$class]) || !isset(self::$privateVarsToReset[$class][$name]))) {
|
if ($saveOriginalValue && (!isset(self::$privateVarsToReset[$class]) || !isset(self::$privateVarsToReset[$class][$valueName]))) {
|
||||||
self::$privateVarsToReset[$class][$valueName] = $reflectionProperty->getValue();
|
self::$privateVarsToReset[$class][$valueName] = $reflectionProperty->getValue();
|
||||||
}
|
}
|
||||||
$reflectionProperty->setValue($value);
|
$reflectionProperty->setValue($value);
|
||||||
|
@ -95,7 +95,7 @@ class SheetTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @param string $fileName
|
* @param string $fileName
|
||||||
* @param string $sheetName
|
* @param string $sheetName
|
||||||
* @return Sheet
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function writeDataAndReturnSheetWithCustomName($fileName, $sheetName)
|
private function writeDataAndReturnSheetWithCustomName($fileName, $sheetName)
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@ class WriterTest extends TestCase
|
|||||||
$writer->addRows($dataRows);
|
$writer->addRows($dataRows);
|
||||||
$this->fail('Exception should have been thrown');
|
$this->fail('Exception should have been thrown');
|
||||||
} catch (SpoutException $e) {
|
} catch (SpoutException $e) {
|
||||||
$this->assertFileNotExists($fileName, 'Output file should have been deleted');
|
$this->assertFileDoesNotExist($fileName, 'Output file should have been deleted');
|
||||||
|
|
||||||
$numFiles = iterator_count(new \FilesystemIterator($tempFolderPath, \FilesystemIterator::SKIP_DOTS));
|
$numFiles = iterator_count(new \FilesystemIterator($tempFolderPath, \FilesystemIterator::SKIP_DOTS));
|
||||||
$this->assertEquals(0, $numFiles, 'All temp files should have been deleted');
|
$this->assertEquals(0, $numFiles, 'All temp files should have been deleted');
|
||||||
@ -291,12 +291,19 @@ class WriterTest extends TestCase
|
|||||||
// Installed locales differ from one system to another, so we can't pick
|
// Installed locales differ from one system to another, so we can't pick
|
||||||
// a given locale.
|
// a given locale.
|
||||||
$supportedLocales = explode("\n", shell_exec('locale -a'));
|
$supportedLocales = explode("\n", shell_exec('locale -a'));
|
||||||
|
$foundCommaLocale = false;
|
||||||
foreach ($supportedLocales as $supportedLocale) {
|
foreach ($supportedLocales as $supportedLocale) {
|
||||||
\setlocale(LC_ALL, $supportedLocale);
|
\setlocale(LC_ALL, $supportedLocale);
|
||||||
if (\localeconv()['decimal_point'] === ',') {
|
if (\localeconv()['decimal_point'] === ',') {
|
||||||
|
$foundCommaLocale = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$foundCommaLocale) {
|
||||||
|
$this->markTestSkipped('No locale with comma decimal separator');
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertEquals(',', \localeconv()['decimal_point']);
|
$this->assertEquals(',', \localeconv()['decimal_point']);
|
||||||
|
|
||||||
$fileName = 'test_add_row_should_support_float_values_in_different_locale.xlsx';
|
$fileName = 'test_add_row_should_support_float_values_in_different_locale.xlsx';
|
||||||
@ -306,8 +313,8 @@ class WriterTest extends TestCase
|
|||||||
|
|
||||||
$this->writeToODSFile($dataRows, $fileName);
|
$this->writeToODSFile($dataRows, $fileName);
|
||||||
|
|
||||||
$this->assertValueWasNotWrittenToSheet($fileName, 1, "1234,5");
|
$this->assertValueWasNotWrittenToSheet($fileName, 1, '1234,5');
|
||||||
$this->assertValueWasWrittenToSheet($fileName, 1, "1234.5");
|
$this->assertValueWasWrittenToSheet($fileName, 1, '1234.5');
|
||||||
} finally {
|
} finally {
|
||||||
// reset locale
|
// reset locale
|
||||||
\setlocale(LC_ALL, $previousLocale);
|
\setlocale(LC_ALL, $previousLocale);
|
||||||
@ -511,6 +518,10 @@ class WriterTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testGeneratedFileShouldHaveTheCorrectMimeType()
|
public function testGeneratedFileShouldHaveTheCorrectMimeType()
|
||||||
{
|
{
|
||||||
|
if (!function_exists('finfo')) {
|
||||||
|
$this->markTestSkipped('finfo is not available on this system (possibly running on Windows where the DLL needs to be added explicitly to the php.ini)');
|
||||||
|
}
|
||||||
|
|
||||||
$fileName = 'test_mime_type.ods';
|
$fileName = 'test_mime_type.ods';
|
||||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
$dataRow = ['foo'];
|
$dataRow = ['foo'];
|
||||||
|
@ -163,7 +163,7 @@ class WriterTest extends TestCase
|
|||||||
$writer->addRows($dataRows);
|
$writer->addRows($dataRows);
|
||||||
$this->fail('Exception should have been thrown');
|
$this->fail('Exception should have been thrown');
|
||||||
} catch (SpoutException $e) {
|
} catch (SpoutException $e) {
|
||||||
$this->assertFileNotExists($fileName, 'Output file should have been deleted');
|
$this->assertFileDoesNotExist($fileName, 'Output file should have been deleted');
|
||||||
|
|
||||||
$numFiles = iterator_count(new \FilesystemIterator($tempFolderPath, \FilesystemIterator::SKIP_DOTS));
|
$numFiles = iterator_count(new \FilesystemIterator($tempFolderPath, \FilesystemIterator::SKIP_DOTS));
|
||||||
$this->assertEquals(0, $numFiles, 'All temp files should have been deleted');
|
$this->assertEquals(0, $numFiles, 'All temp files should have been deleted');
|
||||||
@ -406,12 +406,19 @@ class WriterTest extends TestCase
|
|||||||
// Installed locales differ from one system to another, so we can't pick
|
// Installed locales differ from one system to another, so we can't pick
|
||||||
// a given locale.
|
// a given locale.
|
||||||
$supportedLocales = explode("\n", shell_exec('locale -a'));
|
$supportedLocales = explode("\n", shell_exec('locale -a'));
|
||||||
|
$foundCommaLocale = false;
|
||||||
foreach ($supportedLocales as $supportedLocale) {
|
foreach ($supportedLocales as $supportedLocale) {
|
||||||
\setlocale(LC_ALL, $supportedLocale);
|
\setlocale(LC_ALL, $supportedLocale);
|
||||||
if (\localeconv()['decimal_point'] === ',') {
|
if (\localeconv()['decimal_point'] === ',') {
|
||||||
|
$foundCommaLocale = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$foundCommaLocale) {
|
||||||
|
$this->markTestSkipped('No locale with comma decimal separator');
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertEquals(',', \localeconv()['decimal_point']);
|
$this->assertEquals(',', \localeconv()['decimal_point']);
|
||||||
|
|
||||||
$fileName = 'test_add_row_should_support_float_values_in_different_locale.xlsx';
|
$fileName = 'test_add_row_should_support_float_values_in_different_locale.xlsx';
|
||||||
@ -421,8 +428,8 @@ class WriterTest extends TestCase
|
|||||||
|
|
||||||
$this->writeToXLSXFile($dataRows, $fileName, $shouldUseInlineStrings = false);
|
$this->writeToXLSXFile($dataRows, $fileName, $shouldUseInlineStrings = false);
|
||||||
|
|
||||||
$this->assertInlineDataWasNotWrittenToSheet($fileName, 1, "1234,5");
|
$this->assertInlineDataWasNotWrittenToSheet($fileName, 1, '1234,5');
|
||||||
$this->assertInlineDataWasWrittenToSheet($fileName, 1, "1234.5");
|
$this->assertInlineDataWasWrittenToSheet($fileName, 1, '1234.5');
|
||||||
} finally {
|
} finally {
|
||||||
// reset locale
|
// reset locale
|
||||||
\setlocale(LC_ALL, $previousLocale);
|
\setlocale(LC_ALL, $previousLocale);
|
||||||
@ -568,6 +575,10 @@ class WriterTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testGeneratedFileShouldHaveTheCorrectMimeType()
|
public function testGeneratedFileShouldHaveTheCorrectMimeType()
|
||||||
{
|
{
|
||||||
|
if (!function_exists('finfo')) {
|
||||||
|
$this->markTestSkipped('finfo is not available on this system (possibly running on Windows where the DLL needs to be added explicitly to the php.ini)');
|
||||||
|
}
|
||||||
|
|
||||||
$fileName = 'test_mime_type.xlsx';
|
$fileName = 'test_mime_type.xlsx';
|
||||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
$dataRows = $this->createRowsFromValues([['foo']]);
|
$dataRows = $this->createRowsFromValues([['foo']]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user