Fix 112 Scrutinizer Problems in 1 Module (#2220)

* Fix 112 Scrutinizer Problems in 1 Module

The module is Reader/Xls/Escher - reading pictures from an Xls workbook. The errors fall into precisely 2 categories.
- Assigning a value to a variable which is not subsequently used (35). Although the statements therefore don't accomplish anything, I think they have documentary value for understanding the file layout. So, I have commented out the statements in question rather than deleting them.
- Class property `$this->object` can belong to any of several classes (77). When you invoke a method on it, Scrutinizer and Phpstan flag the statement if not all the candidate classes support the method. Neither has enough information to recognize that the method always exists for any object which reaches the statement. Scrutinizer is noisier about it - it issues a separate message for each class that doesn't support the method, while Phpstan issues a single message. Adding a `method_exists` test is sufficient for Phpstan. We'll see what Scrutinizer thinks when I push the change. If it still doesn't like it, we've eliminated only 35 problems. Phpunit coverage confirms that `method_exists` is always true at the appropriate point.

* Scrutinizer Can Be VERY Annoying

I wasn't looking to do a major rewrite. I was hoping 112 fixes would suffice. Oh well, let's see what happens now.
This commit is contained in:
oleibman 2021-07-26 20:13:26 -07:00 committed by GitHub
parent 51163713c7
commit 188d026615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 209 deletions

View File

@ -2520,76 +2520,6 @@ parameters:
count: 1 count: 1
path: src/PhpSpreadsheet/Reader/Xls/ErrorCode.php path: src/PhpSpreadsheet/Reader/Xls/ErrorCode.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setDggContainer\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setBstoreContainer\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:addBSE\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setBlip\\(\\)\\.$#"
count: 2
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setDgContainer\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:addChild\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:addChild\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setStartCoordinates\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setStartOffsetX\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setStartOffsetY\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setEndCoordinates\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setEndOffsetX\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setEndOffsetY\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setOPT\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xls/Escher.php
- -
message: "#^Parameter \\#1 \\$input of function array_values expects array, array\\|false given\\.$#" message: "#^Parameter \\#1 \\$input of function array_values expects array, array\\|false given\\.$#"
count: 1 count: 1

View File

@ -71,6 +71,27 @@ class Escher
$this->object = $object; $this->object = $object;
} }
private const WHICH_ROUTINE = [
self::DGGCONTAINER => 'readDggContainer',
self::DGG => 'readDgg',
self::BSTORECONTAINER => 'readBstoreContainer',
self::BSE => 'readBSE',
self::BLIPJPEG => 'readBlipJPEG',
self::BLIPPNG => 'readBlipPNG',
self::OPT => 'readOPT',
self::TERTIARYOPT => 'readTertiaryOPT',
self::SPLITMENUCOLORS => 'readSplitMenuColors',
self::DGCONTAINER => 'readDgContainer',
self::DG => 'readDg',
self::SPGRCONTAINER => 'readSpgrContainer',
self::SPCONTAINER => 'readSpContainer',
self::SPGR => 'readSpgr',
self::SP => 'readSp',
self::CLIENTTEXTBOX => 'readClientTextbox',
self::CLIENTANCHOR => 'readClientAnchor',
self::CLIENTDATA => 'readClientData',
];
/** /**
* Load Escher stream data. May be a partial Escher stream. * Load Escher stream data. May be a partial Escher stream.
* *
@ -91,84 +112,9 @@ class Escher
while ($this->pos < $this->dataSize) { while ($this->pos < $this->dataSize) {
// offset: 2; size: 2: Record Type // offset: 2; size: 2: Record Type
$fbt = Xls::getUInt2d($this->data, $this->pos + 2); $fbt = Xls::getUInt2d($this->data, $this->pos + 2);
$routine = self::WHICH_ROUTINE[$fbt] ?? 'readDefault';
switch ($fbt) { if (method_exists($this, $routine)) {
case self::DGGCONTAINER: $this->$routine();
$this->readDggContainer();
break;
case self::DGG:
$this->readDgg();
break;
case self::BSTORECONTAINER:
$this->readBstoreContainer();
break;
case self::BSE:
$this->readBSE();
break;
case self::BLIPJPEG:
$this->readBlipJPEG();
break;
case self::BLIPPNG:
$this->readBlipPNG();
break;
case self::OPT:
$this->readOPT();
break;
case self::TERTIARYOPT:
$this->readTertiaryOPT();
break;
case self::SPLITMENUCOLORS:
$this->readSplitMenuColors();
break;
case self::DGCONTAINER:
$this->readDgContainer();
break;
case self::DG:
$this->readDg();
break;
case self::SPGRCONTAINER:
$this->readSpgrContainer();
break;
case self::SPCONTAINER:
$this->readSpContainer();
break;
case self::SPGR:
$this->readSpgr();
break;
case self::SP:
$this->readSp();
break;
case self::CLIENTTEXTBOX:
$this->readClientTextbox();
break;
case self::CLIENTANCHOR:
$this->readClientAnchor();
break;
case self::CLIENTDATA:
$this->readClientData();
break;
default:
$this->readDefault();
break;
} }
} }
@ -181,16 +127,16 @@ class Escher
private function readDefault(): void private function readDefault(): void
{ {
// offset 0; size: 2; recVer and recInstance // offset 0; size: 2; recVer and recInstance
$verInstance = Xls::getUInt2d($this->data, $this->pos); //$verInstance = Xls::getUInt2d($this->data, $this->pos);
// offset: 2; size: 2: Record Type // offset: 2; size: 2: Record Type
$fbt = Xls::getUInt2d($this->data, $this->pos + 2); //$fbt = Xls::getUInt2d($this->data, $this->pos + 2);
// bit: 0-3; mask: 0x000F; recVer // bit: 0-3; mask: 0x000F; recVer
$recVer = (0x000F & $verInstance) >> 0; //$recVer = (0x000F & $verInstance) >> 0;
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -209,7 +155,7 @@ class Escher
// record is a container, read contents // record is a container, read contents
$dggContainer = new DggContainer(); $dggContainer = new DggContainer();
$this->object->setDggContainer($dggContainer); $this->applyAttribute('setDggContainer', $dggContainer);
$reader = new self($dggContainer); $reader = new self($dggContainer);
$reader->load($recordData); $reader->load($recordData);
} }
@ -220,7 +166,7 @@ class Escher
private function readDgg(): void private function readDgg(): void
{ {
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -239,7 +185,7 @@ class Escher
// record is a container, read contents // record is a container, read contents
$bstoreContainer = new BstoreContainer(); $bstoreContainer = new BstoreContainer();
$this->object->setBstoreContainer($bstoreContainer); $this->applyAttribute('setBstoreContainer', $bstoreContainer);
$reader = new self($bstoreContainer); $reader = new self($bstoreContainer);
$reader->load($recordData); $reader->load($recordData);
} }
@ -262,45 +208,45 @@ class Escher
// add BSE to BstoreContainer // add BSE to BstoreContainer
$BSE = new BSE(); $BSE = new BSE();
$this->object->addBSE($BSE); $this->applyAttribute('addBSE', $BSE);
$BSE->setBLIPType($recInstance); $BSE->setBLIPType($recInstance);
// offset: 0; size: 1; btWin32 (MSOBLIPTYPE) // offset: 0; size: 1; btWin32 (MSOBLIPTYPE)
$btWin32 = ord($recordData[0]); //$btWin32 = ord($recordData[0]);
// offset: 1; size: 1; btWin32 (MSOBLIPTYPE) // offset: 1; size: 1; btWin32 (MSOBLIPTYPE)
$btMacOS = ord($recordData[1]); //$btMacOS = ord($recordData[1]);
// offset: 2; size: 16; MD4 digest // offset: 2; size: 16; MD4 digest
$rgbUid = substr($recordData, 2, 16); //$rgbUid = substr($recordData, 2, 16);
// offset: 18; size: 2; tag // offset: 18; size: 2; tag
$tag = Xls::getUInt2d($recordData, 18); //$tag = Xls::getUInt2d($recordData, 18);
// offset: 20; size: 4; size of BLIP in bytes // offset: 20; size: 4; size of BLIP in bytes
$size = Xls::getInt4d($recordData, 20); //$size = Xls::getInt4d($recordData, 20);
// offset: 24; size: 4; number of references to this BLIP // offset: 24; size: 4; number of references to this BLIP
$cRef = Xls::getInt4d($recordData, 24); //$cRef = Xls::getInt4d($recordData, 24);
// offset: 28; size: 4; MSOFO file offset // offset: 28; size: 4; MSOFO file offset
$foDelay = Xls::getInt4d($recordData, 28); //$foDelay = Xls::getInt4d($recordData, 28);
// offset: 32; size: 1; unused1 // offset: 32; size: 1; unused1
$unused1 = ord($recordData[32]); //$unused1 = ord($recordData[32]);
// offset: 33; size: 1; size of nameData in bytes (including null terminator) // offset: 33; size: 1; size of nameData in bytes (including null terminator)
$cbName = ord($recordData[33]); $cbName = ord($recordData[33]);
// offset: 34; size: 1; unused2 // offset: 34; size: 1; unused2
$unused2 = ord($recordData[34]); //$unused2 = ord($recordData[34]);
// offset: 35; size: 1; unused3 // offset: 35; size: 1; unused3
$unused3 = ord($recordData[35]); //$unused3 = ord($recordData[35]);
// offset: 36; size: $cbName; nameData // offset: 36; size: $cbName; nameData
$nameData = substr($recordData, 36, $cbName); //$nameData = substr($recordData, 36, $cbName);
// offset: 36 + $cbName, size: var; the BLIP data // offset: 36 + $cbName, size: var; the BLIP data
$blipData = substr($recordData, 36 + $cbName); $blipData = substr($recordData, 36 + $cbName);
@ -329,17 +275,17 @@ class Escher
$pos = 0; $pos = 0;
// offset: 0; size: 16; rgbUid1 (MD4 digest of) // offset: 0; size: 16; rgbUid1 (MD4 digest of)
$rgbUid1 = substr($recordData, 0, 16); //$rgbUid1 = substr($recordData, 0, 16);
$pos += 16; $pos += 16;
// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3
if (in_array($recInstance, [0x046B, 0x06E3])) { if (in_array($recInstance, [0x046B, 0x06E3])) {
$rgbUid2 = substr($recordData, 16, 16); //$rgbUid2 = substr($recordData, 16, 16);
$pos += 16; $pos += 16;
} }
// offset: var; size: 1; tag // offset: var; size: 1; tag
$tag = ord($recordData[$pos]); //$tag = ord($recordData[$pos]);
++$pos; ++$pos;
// offset: var; size: var; the raw image data // offset: var; size: var; the raw image data
@ -348,7 +294,7 @@ class Escher
$blip = new Blip(); $blip = new Blip();
$blip->setData($data); $blip->setData($data);
$this->object->setBlip($blip); $this->applyAttribute('setBlip', $blip);
} }
/** /**
@ -370,17 +316,17 @@ class Escher
$pos = 0; $pos = 0;
// offset: 0; size: 16; rgbUid1 (MD4 digest of) // offset: 0; size: 16; rgbUid1 (MD4 digest of)
$rgbUid1 = substr($recordData, 0, 16); //$rgbUid1 = substr($recordData, 0, 16);
$pos += 16; $pos += 16;
// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3
if ($recInstance == 0x06E1) { if ($recInstance == 0x06E1) {
$rgbUid2 = substr($recordData, 16, 16); //$rgbUid2 = substr($recordData, 16, 16);
$pos += 16; $pos += 16;
} }
// offset: var; size: 1; tag // offset: var; size: 1; tag
$tag = ord($recordData[$pos]); //$tag = ord($recordData[$pos]);
++$pos; ++$pos;
// offset: var; size: var; the raw image data // offset: var; size: var; the raw image data
@ -389,7 +335,7 @@ class Escher
$blip = new Blip(); $blip = new Blip();
$blip->setData($data); $blip->setData($data);
$this->object->setBlip($blip); $this->applyAttribute('setBlip', $blip);
} }
/** /**
@ -419,10 +365,10 @@ class Escher
// offset: 0; size: 2; recVer and recInstance // offset: 0; size: 2; recVer and recInstance
// bit: 4-15; mask: 0xFFF0; recInstance // bit: 4-15; mask: 0xFFF0; recInstance
$recInstance = (0xFFF0 & Xls::getUInt2d($this->data, $this->pos)) >> 4; //$recInstance = (0xFFF0 & Xls::getUInt2d($this->data, $this->pos)) >> 4;
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -434,7 +380,7 @@ class Escher
private function readSplitMenuColors(): void private function readSplitMenuColors(): void
{ {
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -453,9 +399,9 @@ class Escher
// record is a container, read contents // record is a container, read contents
$dgContainer = new DgContainer(); $dgContainer = new DgContainer();
$this->object->setDgContainer($dgContainer); $this->applyAttribute('setDgContainer', $dgContainer);
$reader = new self($dgContainer); $reader = new self($dgContainer);
$escher = $reader->load($recordData); $reader->load($recordData);
} }
/** /**
@ -464,7 +410,7 @@ class Escher
private function readDg(): void private function readDg(): void
{ {
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -489,13 +435,13 @@ class Escher
if ($this->object instanceof DgContainer) { if ($this->object instanceof DgContainer) {
// DgContainer // DgContainer
$this->object->setSpgrContainer($spgrContainer); $this->object->setSpgrContainer($spgrContainer);
} else { } elseif ($this->object instanceof SpgrContainer) {
// SpgrContainer // SpgrContainer
$this->object->addChild($spgrContainer); $this->object->addChild($spgrContainer);
} }
$reader = new self($spgrContainer); $reader = new self($spgrContainer);
$escher = $reader->load($recordData); $reader->load($recordData);
} }
/** /**
@ -508,14 +454,14 @@ class Escher
// add spContainer to spgrContainer // add spContainer to spgrContainer
$spContainer = new SpContainer(); $spContainer = new SpContainer();
$this->object->addChild($spContainer); $this->applyAttribute('addChild', $spContainer);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
// record is a container, read contents // record is a container, read contents
$reader = new self($spContainer); $reader = new self($spContainer);
$escher = $reader->load($recordData); $reader->load($recordData);
} }
/** /**
@ -524,7 +470,7 @@ class Escher
private function readSpgr(): void private function readSpgr(): void
{ {
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -538,10 +484,10 @@ class Escher
// offset: 0; size: 2; recVer and recInstance // offset: 0; size: 2; recVer and recInstance
// bit: 4-15; mask: 0xFFF0; recInstance // bit: 4-15; mask: 0xFFF0; recInstance
$recInstance = (0xFFF0 & Xls::getUInt2d($this->data, $this->pos)) >> 4; //$recInstance = (0xFFF0 & Xls::getUInt2d($this->data, $this->pos)) >> 4;
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -555,10 +501,10 @@ class Escher
// offset: 0; size: 2; recVer and recInstance // offset: 0; size: 2; recVer and recInstance
// bit: 4-15; mask: 0xFFF0; recInstance // bit: 4-15; mask: 0xFFF0; recInstance
$recInstance = (0xFFF0 & Xls::getUInt2d($this->data, $this->pos)) >> 4; //$recInstance = (0xFFF0 & Xls::getUInt2d($this->data, $this->pos)) >> 4;
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -599,23 +545,22 @@ class Escher
// offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height // offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height
$endOffsetY = Xls::getUInt2d($recordData, 16); $endOffsetY = Xls::getUInt2d($recordData, 16);
// set the start coordinates $this->applyAttribute('setStartCoordinates', Coordinate::stringFromColumnIndex($c1 + 1) . ($r1 + 1));
$this->object->setStartCoordinates(Coordinate::stringFromColumnIndex($c1 + 1) . ($r1 + 1)); $this->applyAttribute('setStartOffsetX', $startOffsetX);
$this->applyAttribute('setStartOffsetY', $startOffsetY);
$this->applyAttribute('setEndCoordinates', Coordinate::stringFromColumnIndex($c2 + 1) . ($r2 + 1));
$this->applyAttribute('setEndOffsetX', $endOffsetX);
$this->applyAttribute('setEndOffsetY', $endOffsetY);
}
// set the start offsetX /**
$this->object->setStartOffsetX($startOffsetX); * @param mixed $value
*/
// set the start offsetY private function applyAttribute(string $name, $value): void
$this->object->setStartOffsetY($startOffsetY); {
if (method_exists($this->object, $name)) {
// set the end coordinates $this->object->$name($value);
$this->object->setEndCoordinates(Coordinate::stringFromColumnIndex($c2 + 1) . ($r2 + 1)); }
// set the end offsetX
$this->object->setEndOffsetX($endOffsetX);
// set the end offsetY
$this->object->setEndOffsetY($endOffsetY);
} }
/** /**
@ -624,7 +569,7 @@ class Escher
private function readClientData(): void private function readClientData(): void
{ {
$length = Xls::getInt4d($this->data, $this->pos + 4); $length = Xls::getInt4d($this->data, $this->pos + 4);
$recordData = substr($this->data, $this->pos + 8, $length); //$recordData = substr($this->data, $this->pos + 8, $length);
// move stream pointer to next record // move stream pointer to next record
$this->pos += 8 + $length; $this->pos += 8 + $length;
@ -652,7 +597,7 @@ class Escher
$opidOpid = (0x3FFF & $opid) >> 0; $opidOpid = (0x3FFF & $opid) >> 0;
// bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier // bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier
$opidFBid = (0x4000 & $opid) >> 14; //$opidFBid = (0x4000 & $opid) >> 14;
// bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data // bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data
$opidFComplex = (0x8000 & $opid) >> 15; $opidFComplex = (0x8000 & $opid) >> 15;
@ -671,7 +616,9 @@ class Escher
$value = $op; $value = $op;
} }
if (method_exists($this->object, 'setOPT')) {
$this->object->setOPT($opidOpid, $value); $this->object->setOPT($opidOpid, $value);
} }
} }
}
} }