Skip to content

Commit c14a1e6

Browse files
authored
Merge branch 'master' into issue562
2 parents 7a1370c + 817556b commit c14a1e6

31 files changed

+6067
-6173
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org).
99

1010
### Added
1111

12-
- Nothing yet.
12+
- Add Dynamic valueBinder Property to Spreadsheet and Readers. [Issue #1395](https://github.com/PHPOffice/PhpSpreadsheet/issues/1395) [PR #4185](https://github.com/PHPOffice/PhpSpreadsheet/pull/4185)
1313

1414
### Changed
1515

16-
- Nothing yet.
16+
- Refactor Xls Reader. [PR #4118](https://github.com/PHPOffice/PhpSpreadsheet/pull/4118)
1717

1818
### Deprecated
1919

@@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3131
- SUMIFS Does Not Require xlfn. [Issue #4182](https://github.com/PHPOffice/PhpSpreadsheet/issues/4182) [PR #4186](https://github.com/PHPOffice/PhpSpreadsheet/pull/4186)
3232
- Image Transparency/Opacity with Html Reader Changes. [Discussion #4117](https://github.com/PHPOffice/PhpSpreadsheet/discussions/4117) [PR #4142](https://github.com/PHPOffice/PhpSpreadsheet/pull/4142)
3333
- Option to Write Hyperlink Rather Than Label to Csv. [Issue #1412](https://github.com/PHPOffice/PhpSpreadsheet/issues/1412) [PR #4151](https://github.com/PHPOffice/PhpSpreadsheet/pull/4151)
34+
- Invalid Html Due to Cached Filesize. [Issue #1107](https://github.com/PHPOffice/PhpSpreadsheet/issues/1107) [PR #4184](https://github.com/PHPOffice/PhpSpreadsheet/pull/4184)
35+
- Excel 2003 Allows Html Entities. [Issue #2157](https://github.com/PHPOffice/PhpSpreadsheet/issues/2157) [PR #4187](https://github.com/PHPOffice/PhpSpreadsheet/pull/4187)
3436

3537
## 2024-09-29 - 3.3.0 (no 3.0.\*, 3.1.\*, 3.2.\*)
3638

docs/topics/Behind the Mask.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ If you wish to emulate the MS Excel behaviour, and automatically convert string
117117

118118
You can do this by changing the Value Binder, which will then apply every time you set a Cell value.
119119
```php
120+
// Old method using static property
120121
Cell::setValueBinder(new AdvancedValueBinder());
122+
// Preferred method using dynamic property since 3.4.0
123+
$spreadsheet->setValueBinder(new AdvancedValueBinder());
121124

122125
// Set Cell C21 using a formatted string value
123126
$worksheet->getCell('C20')->setValue('€ -12345.6789');

docs/topics/The Dating Game.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,10 @@ $spreadsheet = new Spreadsheet();
257257
$worksheet = $spreadsheet->getActiveSheet();
258258
// Use the Advanced Value Binder so that our string date/time values will be automatically converted
259259
// to Excel serialized date/timestamps
260+
// Old method using static property
260261
Cell::setValueBinder(new AdvancedValueBinder());
262+
// Preferred method using dynamic property since 3.4.0
263+
$spreadsheet->setValueBinder(new AdvancedValueBinder());
261264

262265
// Write our data to the worksheet
263266
$worksheet->fromArray($projectHeading);

docs/topics/accessing-cells.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,15 +518,15 @@ style information. The following example demonstrates how to set the
518518
value binder in PhpSpreadsheet:
519519

520520
```php
521-
/** PhpSpreadsheet */
522-
require_once 'src/Boostrap.php';
523-
524-
// Set value binder
521+
// Older method using static property
525522
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
526-
527523
// Create new Spreadsheet object
528524
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
529525

526+
// Preferred method using dynamic property since 3.4.0
527+
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
528+
$spreadsheet->setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
529+
530530
// ...
531531
// Add some data, resembling some different data types
532532
$spreadsheet->getActiveSheet()->setCellValue('A4', 'Percentage value:');
@@ -555,13 +555,20 @@ $stringValueBinder->setNumericConversion(false)
555555
->setBooleanConversion(false)
556556
->setNullConversion(false)
557557
->setFormulaConversion(false);
558+
// Older method using static property
558559
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( $stringValueBinder );
560+
// Preferred method using dynamic property since 3.4.0
561+
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
562+
$spreadsheet->setValueBinder( $stringValueBinder );
559563
```
560564

561565
You can override the current binder when setting individual cell values by specifying a different Binder to use in the Cell's `setValue()` or the Worksheet's `setCellValue()` methods.
562566
```php
563567
$spreadsheet = new Spreadsheet();
568+
// Old method using static property
564569
Cell::setValueBinder(new AdvancedValueBinder());
570+
// Preferred method using dynamic property since 3.4.0
571+
$spreadsheet->setValueBinder(new AdvancedValueBinder());
565572

566573
$value = '12.5%';
567574

docs/topics/reading-files.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,14 +755,18 @@ So using a Value Binder allows a great deal more flexibility in the
755755
loader logic when reading unformatted text files.
756756

757757
```php
758-
/** Tell PhpSpreadsheet that we want to use the Advanced Value Binder **/
759-
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
760-
761758
$inputFileType = 'Csv';
762759
$inputFileName = './sampleData/example1.tsv';
763760

764761
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
765762
$reader->setDelimiter("\t");
763+
764+
/** Tell PhpSpreadsheet that we want to use the Advanced Value Binder **/
765+
// Old method using static property
766+
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
767+
// Preferred method using dynamic property since 3.4.0
768+
$reader::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
769+
766770
$spreadsheet = $reader->load($inputFileName);
767771
```
768772

@@ -774,7 +778,7 @@ Loading using a Value Binder applies to:
774778
Reader | Y/N |Reader | Y/N |Reader | Y/N
775779
----------|:---:|--------|:---:|--------------|:---:
776780
Xlsx | NO | Xls | NO | Xml | NO
777-
Ods | NO | SYLK | NO | Gnumeric | NO
781+
Ods | NO | SYLK | YES | Gnumeric | NO
778782
CSV | YES | HTML | YES
779783

780784
Note that you can also use the Binder to determine how PhpSpreadsheet identified datatypes for values when you set a cell value without explicitly setting a datatype.

docs/topics/recipes.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,10 @@ method that suits you the best. Here are some examples:
233233

234234
```php
235235
// MySQL-like timestamp '2008-12-31' or date string
236+
// Old method using static property
236237
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
238+
// Preferred method using dynamic property since 3.4.0
239+
$spreadsheet->setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
237240

238241
$spreadsheet->getActiveSheet()
239242
->setCellValue('D1', '2008-12-31');
@@ -599,7 +602,10 @@ when it sees a newline character in a string that you are inserting in a
599602
cell. Just like Microsoft Office Excel. Try this:
600603

601604
```php
605+
// Old method using static property
602606
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
607+
// Preferred method using dynamic property since 3.4.0
608+
$spreadsheet->setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
603609

604610
$spreadsheet->getActiveSheet()->getCell('A1')->setValue("hello\nworld");
605611
```

src/PhpSpreadsheet/Cell/Cell.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,11 @@ public function __construct(mixed $value, ?string $dataType, Worksheet $workshee
112112
$dataType = DataType::TYPE_STRING;
113113
}
114114
$this->dataType = $dataType;
115-
} elseif (self::getValueBinder()->bindValue($this, $value) === false) {
116-
throw new SpreadsheetException('Value could not be bound to cell.');
115+
} else {
116+
$valueBinder = $worksheet->getParent()?->getValueBinder() ?? self::getValueBinder();
117+
if ($valueBinder->bindValue($this, $value) === false) {
118+
throw new SpreadsheetException('Value could not be bound to cell.');
119+
}
117120
}
118121
$this->ignoredErrors = new IgnoredErrors();
119122
}
@@ -232,7 +235,8 @@ protected static function updateIfCellIsTableHeader(?Worksheet $workSheet, self
232235
*/
233236
public function setValue(mixed $value, ?IValueBinder $binder = null): self
234237
{
235-
$binder ??= self::getValueBinder();
238+
// Cells?->Worksheet?->Spreadsheet
239+
$binder ??= $this->parent?->getParent()?->getParent()?->getValueBinder() ?? self::getValueBinder();
236240
if (!$binder->bindValue($this, $value)) {
237241
throw new SpreadsheetException('Value could not be bound to cell.');
238242
}

src/PhpSpreadsheet/Reader/BaseReader.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Reader;
44

5+
use PhpOffice\PhpSpreadsheet\Cell\IValueBinder;
56
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
67
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
78
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
@@ -56,6 +57,8 @@ abstract class BaseReader implements IReader
5657

5758
protected ?XmlScanner $securityScanner = null;
5859

60+
protected ?IValueBinder $valueBinder = null;
61+
5962
public function __construct()
6063
{
6164
$this->readFilter = new DefaultReadFilter();
@@ -242,4 +245,16 @@ public function listWorksheetNames(string $filename): array
242245

243246
return $returnArray;
244247
}
248+
249+
public function getValueBinder(): ?IValueBinder
250+
{
251+
return $this->valueBinder;
252+
}
253+
254+
public function setValueBinder(?IValueBinder $valueBinder): self
255+
{
256+
$this->valueBinder = $valueBinder;
257+
258+
return $this;
259+
}
245260
}

src/PhpSpreadsheet/Reader/Csv.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
262262
{
263263
// Create new Spreadsheet
264264
$spreadsheet = new Spreadsheet();
265+
$spreadsheet->setValueBinder($this->valueBinder);
265266

266267
// Load into this instance
267268
return $this->loadIntoExisting($filename, $spreadsheet);
@@ -274,6 +275,7 @@ public function loadSpreadsheetFromString(string $contents): Spreadsheet
274275
{
275276
// Create new Spreadsheet
276277
$spreadsheet = new Spreadsheet();
278+
$spreadsheet->setValueBinder($this->valueBinder);
277279

278280
// Load into this instance
279281
return $this->loadStringOrFile('data://text/plain,' . urlencode($contents), $spreadsheet, true);
@@ -391,7 +393,7 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
391393
// Loop through each line of the file in turn
392394
$delimiter = $this->delimiter ?? '';
393395
$rowData = self::getCsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
394-
$valueBinder = Cell::getValueBinder();
396+
$valueBinder = $this->valueBinder ?? Cell::getValueBinder();
395397
$preserveBooleanString = method_exists($valueBinder, 'getBooleanConversion') && $valueBinder->getBooleanConversion();
396398
$this->getTrue = Calculation::getTRUE();
397399
$this->getFalse = Calculation::getFALSE();

src/PhpSpreadsheet/Reader/Gnumeric.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
226226
{
227227
// Create new Spreadsheet
228228
$spreadsheet = new Spreadsheet();
229+
$spreadsheet->setValueBinder($this->valueBinder);
229230
$spreadsheet->removeSheetByIndex(0);
230231

231232
// Load into this instance

0 commit comments

Comments
 (0)