@@ -15,10 +15,12 @@ class ReferenceHelper
15
15
{
16
16
/** Constants */
17
17
/** Regular Expressions */
18
- const REFHELPER_REGEXP_CELLREF = '((\w*| \'[^!]* \')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d \']) ' ;
19
- const REFHELPER_REGEXP_CELLRANGE = '((\w*| \'[^!]* \')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+) ' ;
20
- const REFHELPER_REGEXP_ROWRANGE = '((\w*| \'[^!]* \')!)?(\$?\d+):(\$?\d+) ' ;
21
- const REFHELPER_REGEXP_COLRANGE = '((\w*| \'[^!]* \')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3}) ' ;
18
+ private const SHEETNAME_PART = '((\w*| \'[^!]* \')!) ' ;
19
+ private const SHEETNAME_PART_WITH_SLASHES = '/ ' . self ::SHEETNAME_PART . '/ ' ;
20
+ const REFHELPER_REGEXP_CELLREF = self ::SHEETNAME_PART . '?(?<![:a-z1-9_\.\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d \']) ' ;
21
+ const REFHELPER_REGEXP_CELLRANGE = self ::SHEETNAME_PART . '?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+) ' ;
22
+ const REFHELPER_REGEXP_ROWRANGE = self ::SHEETNAME_PART . '?(\$?\d+):(\$?\d+) ' ;
23
+ const REFHELPER_REGEXP_COLRANGE = self ::SHEETNAME_PART . '?(\$?[a-z]{1,3}):(\$?[a-z]{1,3}) ' ;
22
24
23
25
/**
24
26
* Instance of this class.
@@ -545,6 +547,18 @@ public function insertNewBefore(
545
547
$ worksheet ->garbageCollect ();
546
548
}
547
549
550
+ private static function matchSheetName (?string $ match , string $ worksheetName ): bool
551
+ {
552
+ return $ match === null || $ match === '' || $ match === "' \u{fffc}' " || $ match === "' \u{fffb}' " || strcasecmp (trim ($ match , "' " ), $ worksheetName ) === 0 ;
553
+ }
554
+
555
+ private static function sheetnameBeforeCells (string $ match , string $ worksheetName , string $ cells ): string
556
+ {
557
+ $ toString = ($ match > '' ) ? "$ match! " : '' ;
558
+
559
+ return str_replace (["\u{fffc}" , "' \u{fffb}' " ], $ worksheetName , $ toString ) . $ cells ;
560
+ }
561
+
548
562
/**
549
563
* Update references within formulas.
550
564
*
@@ -565,6 +579,7 @@ public function updateFormulaReferences(
565
579
bool $ includeAbsoluteReferences = false ,
566
580
bool $ onlyAbsoluteReferences = false
567
581
): string {
582
+ $ callback = fn (array $ matches ): string => (strcasecmp (trim ($ matches [2 ], "' " ), $ worksheetName ) === 0 ) ? (($ matches [2 ][0 ] === "' " ) ? "' \u{fffc}'! " : "' \u{fffb}'! " ) : "' \u{fffd}'! " ;
568
583
if (
569
584
$ this ->cellReferenceHelper === null
570
585
|| $ this ->cellReferenceHelper ->refreshRequired ($ beforeCellAddress , $ numberOfColumns , $ numberOfRows )
@@ -582,18 +597,17 @@ public function updateFormulaReferences(
582
597
$ adjustCount = 0 ;
583
598
$ newCellTokens = $ cellTokens = [];
584
599
// Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5)
585
- $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_ROWRANGE . '/mui ' , ' ' . $ formulaBlock . ' ' , $ matches , PREG_SET_ORDER );
600
+ $ formulaBlockx = ' ' . (preg_replace_callback (self ::SHEETNAME_PART_WITH_SLASHES , $ callback , $ formulaBlock ) ?? $ formulaBlock ) . ' ' ;
601
+ $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_ROWRANGE . '/mui ' , $ formulaBlockx , $ matches , PREG_SET_ORDER );
586
602
if ($ matchCount > 0 ) {
587
603
foreach ($ matches as $ match ) {
588
- $ fromString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
589
- $ fromString .= $ match [3 ] . ': ' . $ match [4 ];
604
+ $ fromString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "{$ match [3 ]}: {$ match [4 ]}" );
590
605
$ modified3 = substr ($ this ->updateCellReference ('$A ' . $ match [3 ], $ includeAbsoluteReferences , $ onlyAbsoluteReferences ), 2 );
591
606
$ modified4 = substr ($ this ->updateCellReference ('$A ' . $ match [4 ], $ includeAbsoluteReferences , $ onlyAbsoluteReferences ), 2 );
592
607
593
608
if ($ match [3 ] . ': ' . $ match [4 ] !== $ modified3 . ': ' . $ modified4 ) {
594
- if (($ match [2 ] == '' ) || (trim ($ match [2 ], "' " ) == $ worksheetName )) {
595
- $ toString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
596
- $ toString .= $ modified3 . ': ' . $ modified4 ;
609
+ if (self ::matchSheetName ($ match [2 ], $ worksheetName )) {
610
+ $ toString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "$ modified3: $ modified4 " );
597
611
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
598
612
$ column = 100000 ;
599
613
$ row = 10000000 + (int ) trim ($ match [3 ], '$ ' );
@@ -607,18 +621,17 @@ public function updateFormulaReferences(
607
621
}
608
622
}
609
623
// Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E)
610
- $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_COLRANGE . '/mui ' , ' ' . $ formulaBlock . ' ' , $ matches , PREG_SET_ORDER );
624
+ $ formulaBlockx = ' ' . (preg_replace_callback (self ::SHEETNAME_PART_WITH_SLASHES , $ callback , $ formulaBlock ) ?? $ formulaBlock ) . ' ' ;
625
+ $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_COLRANGE . '/mui ' , $ formulaBlockx , $ matches , PREG_SET_ORDER );
611
626
if ($ matchCount > 0 ) {
612
627
foreach ($ matches as $ match ) {
613
- $ fromString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
614
- $ fromString .= $ match [3 ] . ': ' . $ match [4 ];
628
+ $ fromString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "{$ match [3 ]}: {$ match [4 ]}" );
615
629
$ modified3 = substr ($ this ->updateCellReference ($ match [3 ] . '$1 ' , $ includeAbsoluteReferences , $ onlyAbsoluteReferences ), 0 , -2 );
616
630
$ modified4 = substr ($ this ->updateCellReference ($ match [4 ] . '$1 ' , $ includeAbsoluteReferences , $ onlyAbsoluteReferences ), 0 , -2 );
617
631
618
632
if ($ match [3 ] . ': ' . $ match [4 ] !== $ modified3 . ': ' . $ modified4 ) {
619
- if (($ match [2 ] == '' ) || (trim ($ match [2 ], "' " ) == $ worksheetName )) {
620
- $ toString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
621
- $ toString .= $ modified3 . ': ' . $ modified4 ;
633
+ if (self ::matchSheetName ($ match [2 ], $ worksheetName )) {
634
+ $ toString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "$ modified3: $ modified4 " );
622
635
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
623
636
$ column = Coordinate::columnIndexFromString (trim ($ match [3 ], '$ ' )) + 100000 ;
624
637
$ row = 10000000 ;
@@ -632,18 +645,17 @@ public function updateFormulaReferences(
632
645
}
633
646
}
634
647
// Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5)
635
- $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_CELLRANGE . '/mui ' , ' ' . $ formulaBlock . ' ' , $ matches , PREG_SET_ORDER );
648
+ $ formulaBlockx = ' ' . (preg_replace_callback (self ::SHEETNAME_PART_WITH_SLASHES , $ callback , "$ formulaBlock " ) ?? "$ formulaBlock " ) . ' ' ;
649
+ $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_CELLRANGE . '/mui ' , $ formulaBlockx , $ matches , PREG_SET_ORDER );
636
650
if ($ matchCount > 0 ) {
637
651
foreach ($ matches as $ match ) {
638
- $ fromString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
639
- $ fromString .= $ match [3 ] . ': ' . $ match [4 ];
652
+ $ fromString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "{$ match [3 ]}: {$ match [4 ]}" );
640
653
$ modified3 = $ this ->updateCellReference ($ match [3 ], $ includeAbsoluteReferences , $ onlyAbsoluteReferences );
641
654
$ modified4 = $ this ->updateCellReference ($ match [4 ], $ includeAbsoluteReferences , $ onlyAbsoluteReferences );
642
655
643
656
if ($ match [3 ] . $ match [4 ] !== $ modified3 . $ modified4 ) {
644
- if (($ match [2 ] == '' ) || (trim ($ match [2 ], "' " ) == $ worksheetName )) {
645
- $ toString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
646
- $ toString .= $ modified3 . ': ' . $ modified4 ;
657
+ if (self ::matchSheetName ($ match [2 ], $ worksheetName )) {
658
+ $ toString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "$ modified3: $ modified4 " );
647
659
[$ column , $ row ] = Coordinate::coordinateFromString ($ match [3 ]);
648
660
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
649
661
$ column = Coordinate::columnIndexFromString (trim ($ column , '$ ' )) + 100000 ;
@@ -658,18 +670,18 @@ public function updateFormulaReferences(
658
670
}
659
671
}
660
672
// Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5)
661
- $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_CELLREF . '/mui ' , ' ' . $ formulaBlock . ' ' , $ matches , PREG_SET_ORDER );
673
+
674
+ $ formulaBlockx = ' ' . (preg_replace_callback (self ::SHEETNAME_PART_WITH_SLASHES , $ callback , $ formulaBlock ) ?? $ formulaBlock ) . ' ' ;
675
+ $ matchCount = preg_match_all ('/ ' . self ::REFHELPER_REGEXP_CELLREF . '/mui ' , $ formulaBlockx , $ matches , PREG_SET_ORDER );
662
676
663
677
if ($ matchCount > 0 ) {
664
678
foreach ($ matches as $ match ) {
665
- $ fromString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
666
- $ fromString .= $ match [3 ];
679
+ $ fromString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "{$ match [3 ]}" );
667
680
668
681
$ modified3 = $ this ->updateCellReference ($ match [3 ], $ includeAbsoluteReferences , $ onlyAbsoluteReferences );
669
682
if ($ match [3 ] !== $ modified3 ) {
670
- if (($ match [2 ] == '' ) || (trim ($ match [2 ], "' " ) == $ worksheetName )) {
671
- $ toString = ($ match [2 ] > '' ) ? $ match [2 ] . '! ' : '' ;
672
- $ toString .= $ modified3 ;
683
+ if (self ::matchSheetName ($ match [2 ], $ worksheetName )) {
684
+ $ toString = self ::sheetnameBeforeCells ($ match [2 ], $ worksheetName , "$ modified3 " );
673
685
[$ column , $ row ] = Coordinate::coordinateFromString ($ match [3 ]);
674
686
$ columnAdditionalIndex = $ column [0 ] === '$ ' ? 1 : 0 ;
675
687
$ rowAdditionalIndex = $ row [0 ] === '$ ' ? 1 : 0 ;
0 commit comments