Prep Work for Phpstan Upgrade (#2728)
Dependabot submitted PRs #2719 and #2720 to upgrade Phpstan. As with most Phpstan upgrades, there are new error messages; this PR is an attempt to fix all 58 of the new problems in order to allow the upgrade to proceed. Most of these fixes involve the addition of doc-block type annotations, often involving the assignment of the 'objectionable' portion of the statement to a new variable. Some use explicit casting when I am sure that's safe. Some (Reader/Ods) involve defeating result caching by Phpstan.
This commit is contained in:
parent
28bb2cd7c7
commit
64e61d8dec
|
|
@ -340,11 +340,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\BesselK\\:\\:besselK2\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Engineering/BesselK.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ConvertBase\\:\\:validatePlaces\\(\\) has parameter \\$places with no type specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -2070,11 +2065,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^If condition is always true\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:listWorksheetNames\\(\\) should return array\\<string\\> but returns array\\<int, string\\|null\\>\\.$#"
|
||||
count: 1
|
||||
|
|
@ -2095,11 +2085,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^While loop condition is always true\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Reader/Ods.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getElementsByTagNameNS\\(\\) on DOMElement\\|null\\.$#"
|
||||
count: 3
|
||||
|
|
@ -3880,11 +3865,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Shared/Trend/Trend.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$order of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\PolynomialBestFit constructor expects int, string given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Shared/Trend/Trend.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\XMLWriter\\:\\:getData\\(\\) should return string but returns string\\|false\\.$#"
|
||||
count: 1
|
||||
|
|
|
|||
|
|
@ -68,13 +68,28 @@ class BesselK
|
|||
return self::besselK2($x, $ord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mollify Phpstan.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private static function callBesselI(float $x, int $ord): float
|
||||
{
|
||||
$rslt = BesselI::BESSELI($x, $ord);
|
||||
if (!is_float($rslt)) {
|
||||
throw new Exception('Unexpected array or string');
|
||||
}
|
||||
|
||||
return $rslt;
|
||||
}
|
||||
|
||||
private static function besselK0(float $x): float
|
||||
{
|
||||
if ($x <= 2) {
|
||||
$fNum2 = $x * 0.5;
|
||||
$y = ($fNum2 * $fNum2);
|
||||
|
||||
return -log($fNum2) * BesselI::BESSELI($x, 0) +
|
||||
return -log($fNum2) * self::callBesselI($x, 0) +
|
||||
(-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y *
|
||||
(0.10750e-3 + $y * 0.74e-5))))));
|
||||
}
|
||||
|
|
@ -92,7 +107,7 @@ class BesselK
|
|||
$fNum2 = $x * 0.5;
|
||||
$y = ($fNum2 * $fNum2);
|
||||
|
||||
return log($fNum2) * BesselI::BESSELI($x, 1) +
|
||||
return log($fNum2) * self::callBesselI($x, 1) +
|
||||
(1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y *
|
||||
(-0.110404e-2 + $y * (-0.4686e-4))))))) / $x;
|
||||
}
|
||||
|
|
@ -104,7 +119,7 @@ class BesselK
|
|||
(0.325614e-2 + $y * (-0.68245e-3)))))));
|
||||
}
|
||||
|
||||
private static function besselK2(float $x, int $ord)
|
||||
private static function besselK2(float $x, int $ord): float
|
||||
{
|
||||
$fTox = 2 / $x;
|
||||
$fBkm = self::besselK0($x);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,21 @@ class BesselY
|
|||
return self::besselY2($x, $ord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mollify Phpstan.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private static function callBesselJ(float $x, int $ord): float
|
||||
{
|
||||
$rslt = BesselJ::BESSELJ($x, $ord);
|
||||
if (!is_float($rslt)) {
|
||||
throw new Exception('Unexpected array or string');
|
||||
}
|
||||
|
||||
return $rslt;
|
||||
}
|
||||
|
||||
private static function besselY0(float $x): float
|
||||
{
|
||||
if ($x < 8.0) {
|
||||
|
|
@ -75,7 +90,7 @@ class BesselY
|
|||
$ans2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y *
|
||||
(47447.26470 + $y * (226.1030244 + $y))));
|
||||
|
||||
return $ans1 / $ans2 + 0.636619772 * BesselJ::BESSELJ($x, 0) * log($x);
|
||||
return $ans1 / $ans2 + 0.636619772 * self::callBesselJ($x, 0) * log($x);
|
||||
}
|
||||
|
||||
$z = 8.0 / $x;
|
||||
|
|
@ -97,7 +112,7 @@ class BesselY
|
|||
$ans2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y *
|
||||
(0.1020426050e6 + $y * (0.3549632885e3 + $y)))));
|
||||
|
||||
return ($ans1 / $ans2) + 0.636619772 * (BesselJ::BESSELJ($x, 1) * log($x) - 1 / $x);
|
||||
return ($ans1 / $ans2) + 0.636619772 * (self::callBesselJ($x, 1) * log($x) - 1 / $x);
|
||||
}
|
||||
|
||||
$z = 8.0 / $x;
|
||||
|
|
|
|||
|
|
@ -70,10 +70,12 @@ class Amortization
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$yearFrac = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);
|
||||
if (is_string($yearFrac)) {
|
||||
return $yearFrac;
|
||||
$yearFracx = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);
|
||||
if (is_string($yearFracx)) {
|
||||
return $yearFracx;
|
||||
}
|
||||
/** @var float */
|
||||
$yearFrac = $yearFracx;
|
||||
|
||||
$amortiseCoeff = self::getAmortizationCoefficient($rate);
|
||||
|
||||
|
|
@ -161,10 +163,12 @@ class Amortization
|
|||
$fCostDelta = $cost - $salvage;
|
||||
// Note, quirky variation for leap years on the YEARFRAC for this function
|
||||
$purchasedYear = DateTimeExcel\DateParts::year($purchased);
|
||||
$yearFrac = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);
|
||||
if (is_string($yearFrac)) {
|
||||
return $yearFrac;
|
||||
$yearFracx = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);
|
||||
if (is_string($yearFracx)) {
|
||||
return $yearFracx;
|
||||
}
|
||||
/** @var float */
|
||||
$yearFrac = $yearFracx;
|
||||
|
||||
if (
|
||||
($basis == FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL) &&
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ class Coupons
|
|||
return $e->getMessage();
|
||||
}
|
||||
|
||||
/** @var int */
|
||||
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
|
||||
$next = self::couponFirstPeriodDate($settlement, $maturity, $frequency, self::PERIOD_DATE_NEXT);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,9 @@ class Confidence
|
|||
if (($alpha <= 0) || ($alpha >= 1) || ($stdDev <= 0) || ($size < 1)) {
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
/** @var float */
|
||||
$temp = Distributions\StandardNormal::inverse(1 - $alpha / 2);
|
||||
|
||||
return Functions::scalar(Distributions\StandardNormal::inverse(1 - $alpha / 2) * $stdDev / sqrt($size));
|
||||
return Functions::scalar($temp * $stdDev / sqrt($size));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,8 +56,10 @@ class Binomial
|
|||
if ($cumulative) {
|
||||
return self::calculateCumulativeBinomial($value, $trials, $probability);
|
||||
}
|
||||
/** @var float */
|
||||
$comb = Combinations::withoutRepetition($trials, $value);
|
||||
|
||||
return Combinations::withoutRepetition($trials, $value) * $probability ** $value
|
||||
return $comb * $probability ** $value
|
||||
* (1 - $probability) ** ($trials - $value);
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +109,9 @@ class Binomial
|
|||
|
||||
$summer = 0;
|
||||
for ($i = $successes; $i <= $limit; ++$i) {
|
||||
$summer += Combinations::withoutRepetition($trials, $i) * $probability ** $i
|
||||
/** @var float */
|
||||
$comb = Combinations::withoutRepetition($trials, $i);
|
||||
$summer += $comb * $probability ** $i
|
||||
* (1 - $probability) ** ($trials - $i);
|
||||
}
|
||||
|
||||
|
|
@ -159,8 +163,10 @@ class Binomial
|
|||
return ExcelError::NAN();
|
||||
}
|
||||
}
|
||||
/** @var float */
|
||||
$comb = Combinations::withoutRepetition($failures + $successes - 1, $successes - 1);
|
||||
|
||||
return (Combinations::withoutRepetition($failures + $successes - 1, $successes - 1))
|
||||
return $comb
|
||||
* ($probability ** $successes) * ((1 - $probability) ** $failures);
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +226,9 @@ class Binomial
|
|||
{
|
||||
$summer = 0;
|
||||
for ($i = 0; $i <= $value; ++$i) {
|
||||
$summer += Combinations::withoutRepetition($trials, $i) * $probability ** $i
|
||||
/** @var float */
|
||||
$comb = Combinations::withoutRepetition($trials, $i);
|
||||
$summer += $comb * $probability ** $i
|
||||
* (1 - $probability) ** ($trials - $i);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ class ChiSquared
|
|||
// Relative error controlled by the eps parameter
|
||||
private static function gser($n, $x)
|
||||
{
|
||||
/** @var float */
|
||||
$gln = Gamma::ln($n / 2);
|
||||
$a = 0.5 * $n;
|
||||
$ap = $a;
|
||||
|
|
@ -304,6 +305,7 @@ class ChiSquared
|
|||
// Relative error controlled by the eps parameter
|
||||
private static function gcf($n, $x)
|
||||
{
|
||||
/** @var float */
|
||||
$gln = Gamma::ln($n / 2);
|
||||
$a = 0.5 * $n;
|
||||
$b = $x + 1 - $a;
|
||||
|
|
|
|||
|
|
@ -131,7 +131,9 @@ class LogNormal
|
|||
if ($stdDev <= 0) {
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
/** @var float */
|
||||
$inverse = StandardNormal::inverse($probability);
|
||||
|
||||
return exp($mean + $stdDev * StandardNormal::inverse($probability));
|
||||
return exp($mean + $stdDev * $inverse);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,12 +51,16 @@ class Poisson
|
|||
$summer = 0;
|
||||
$floor = floor($value);
|
||||
for ($i = 0; $i <= $floor; ++$i) {
|
||||
$summer += $mean ** $i / MathTrig\Factorial::fact($i);
|
||||
/** @var float */
|
||||
$fact = MathTrig\Factorial::fact($i);
|
||||
$summer += $mean ** $i / $fact;
|
||||
}
|
||||
|
||||
return exp(0 - $mean) * $summer;
|
||||
}
|
||||
/** @var float */
|
||||
$fact = MathTrig\Factorial::fact($value);
|
||||
|
||||
return (exp(0 - $mean) * $mean ** $value) / MathTrig\Factorial::fact($value);
|
||||
return (exp(0 - $mean) * $mean ** $value) / $fact;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,8 +103,10 @@ class StandardNormal
|
|||
if (!is_numeric($value)) {
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
/** @var float */
|
||||
$dist = self::distribution($value, true);
|
||||
|
||||
return self::distribution($value, true) - 0.5;
|
||||
return $dist - 0.5;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,6 +141,7 @@ class StandardNormal
|
|||
}
|
||||
|
||||
if ($sigma === null) {
|
||||
/** @var float */
|
||||
$sigma = StandardDeviations::STDEV($dataSet);
|
||||
}
|
||||
$n = count($dataSet);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class Size
|
|||
$mArgs = self::filter($aArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
if ($count === 0 || $entry < 0 || $entry >= $count) {
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
rsort($mArgs);
|
||||
|
|
@ -67,7 +67,7 @@ class Size
|
|||
$mArgs = self::filter($aArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
if ($count === 0 || $entry < 0 || $entry >= $count) {
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
sort($mArgs);
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder
|
|||
{
|
||||
// Convert value to number
|
||||
[$hours, $minutes] = explode(':', $value);
|
||||
$hours = (int) $hours;
|
||||
$minutes = (int) $minutes;
|
||||
$days = ($hours / 24) + ($minutes / 1440);
|
||||
$cell->setValueExplicit($days, DataType::TYPE_NUMERIC);
|
||||
|
||||
|
|
@ -193,6 +195,9 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder
|
|||
{
|
||||
// Convert value to number
|
||||
[$hours, $minutes, $seconds] = explode(':', $value);
|
||||
$hours = (int) $hours;
|
||||
$minutes = (int) $minutes;
|
||||
$seconds = (int) $seconds;
|
||||
$days = ($hours / 24) + ($minutes / 1440) + ($seconds / 86400);
|
||||
$cell->setValueExplicit($days, DataType::TYPE_NUMERIC);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class Ods extends BaseReader
|
|||
$xml->read();
|
||||
while ($xml->read()) {
|
||||
// Quickly jump through to the office:body node
|
||||
while ($xml->name !== 'office:body') {
|
||||
while (self::getXmlName($xml) !== 'office:body') {
|
||||
if ($xml->isEmptyElement) {
|
||||
$xml->read();
|
||||
} else {
|
||||
|
|
@ -114,12 +114,13 @@ class Ods extends BaseReader
|
|||
}
|
||||
// Now read each node until we find our first table:table node
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$xmlName = self::getXmlName($xml);
|
||||
if ($xmlName == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
// Loop through each table:table node reading the table:name attribute for each worksheet name
|
||||
do {
|
||||
$worksheetNames[] = $xml->getAttribute('table:name');
|
||||
$xml->next();
|
||||
} while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
|
||||
} while (self::getXmlName($xml) == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -152,7 +153,7 @@ class Ods extends BaseReader
|
|||
$xml->read();
|
||||
while ($xml->read()) {
|
||||
// Quickly jump through to the office:body node
|
||||
while ($xml->name !== 'office:body') {
|
||||
while (self::getXmlName($xml) !== 'office:body') {
|
||||
if ($xml->isEmptyElement) {
|
||||
$xml->read();
|
||||
} else {
|
||||
|
|
@ -161,7 +162,7 @@ class Ods extends BaseReader
|
|||
}
|
||||
// Now read each node until we find our first table:table node
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (self::getXmlName($xml) == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$worksheetNames[] = $xml->getAttribute('table:name');
|
||||
|
||||
$tmpInfo = [
|
||||
|
|
@ -176,7 +177,7 @@ class Ods extends BaseReader
|
|||
$currCells = 0;
|
||||
do {
|
||||
$xml->read();
|
||||
if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (self::getXmlName($xml) == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$rowspan = $xml->getAttribute('table:number-rows-repeated');
|
||||
$rowspan = empty($rowspan) ? 1 : $rowspan;
|
||||
$tmpInfo['totalRows'] += $rowspan;
|
||||
|
|
@ -186,22 +187,22 @@ class Ods extends BaseReader
|
|||
$xml->read();
|
||||
do {
|
||||
$doread = true;
|
||||
if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (self::getXmlName($xml) == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (!$xml->isEmptyElement) {
|
||||
++$currCells;
|
||||
$xml->next();
|
||||
$doread = false;
|
||||
}
|
||||
} elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
} elseif (self::getXmlName($xml) == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
|
||||
$currCells += (int) $mergeSize;
|
||||
}
|
||||
if ($doread) {
|
||||
$xml->read();
|
||||
}
|
||||
} while ($xml->name != 'table:table-row');
|
||||
} while (self::getXmlName($xml) != 'table:table-row');
|
||||
}
|
||||
} while ($xml->name != 'table:table');
|
||||
} while (self::getXmlName($xml) != 'table:table');
|
||||
|
||||
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
|
||||
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
|
||||
|
|
@ -214,6 +215,16 @@ class Ods extends BaseReader
|
|||
return $worksheetInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counteract Phpstan caching.
|
||||
*
|
||||
* @phpstan-impure
|
||||
*/
|
||||
private static function getXmlName(XMLReader $xml): string
|
||||
{
|
||||
return $xml->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads PhpSpreadsheet from file.
|
||||
*/
|
||||
|
|
@ -681,12 +692,7 @@ class Ods extends BaseReader
|
|||
// Multiple spaces?
|
||||
/** @var DOMAttr $cAttr */
|
||||
$cAttr = $child->attributes->getNamedItem('c');
|
||||
if ($cAttr) {
|
||||
$multiplier = (int) $cAttr->nodeValue;
|
||||
} else {
|
||||
$multiplier = 1;
|
||||
}
|
||||
|
||||
$multiplier = self::getMultiplier($cAttr);
|
||||
$str .= str_repeat(' ', $multiplier);
|
||||
}
|
||||
|
||||
|
|
@ -698,6 +704,17 @@ class Ods extends BaseReader
|
|||
return $str;
|
||||
}
|
||||
|
||||
private static function getMultiplier(?DOMAttr $cAttr): int
|
||||
{
|
||||
if ($cAttr) {
|
||||
$multiplier = (int) $cAttr->nodeValue;
|
||||
} else {
|
||||
$multiplier = 1;
|
||||
}
|
||||
|
||||
return $multiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $is
|
||||
*
|
||||
|
|
|
|||
|
|
@ -894,7 +894,7 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
|
||||
foreach ($xmlSheet->extLst->ext->children('x14', true)->dataValidations->dataValidation as $item) {
|
||||
$node = $xmlSheet->dataValidations->addChild('dataValidation');
|
||||
$node = self::testSimpleXml($xmlSheet->dataValidations)->addChild('dataValidation');
|
||||
foreach ($item->attributes() ?? [] as $attr) {
|
||||
$node->addAttribute($attr->getName(), $attr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class Trend
|
|||
case self::TREND_POLYNOMIAL_5:
|
||||
case self::TREND_POLYNOMIAL_6:
|
||||
if (!isset(self::$trendCache[$key])) {
|
||||
$order = substr($trendType, -1);
|
||||
$order = (int) substr($trendType, -1);
|
||||
self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues);
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ class Trend
|
|||
}
|
||||
if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
|
||||
foreach (self::$trendTypePolynomialOrders as $trendMethod) {
|
||||
$order = substr($trendMethod, -1);
|
||||
$order = (int) substr($trendMethod, -1);
|
||||
$bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues);
|
||||
if ($bestFit[$trendMethod]->getError()) {
|
||||
unset($bestFit[$trendMethod]);
|
||||
|
|
|
|||
|
|
@ -293,7 +293,10 @@ class Color extends Supervisor
|
|||
*/
|
||||
private static function getColourComponent($rgbValue, $offset, $hex = true)
|
||||
{
|
||||
$colour = substr($rgbValue, $offset, 2);
|
||||
$colour = substr($rgbValue, $offset, 2) ?: '';
|
||||
if (preg_match('/^[0-9a-f]{2}$/i', $colour) !== 1) {
|
||||
$colour = '00';
|
||||
}
|
||||
|
||||
return ($hex) ? $colour : (int) hexdec($colour);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,12 @@ class FractionFormatter extends BaseFormatter
|
|||
$decimalLength = strlen($decimalPart);
|
||||
$decimalDivisor = 10 ** $decimalLength;
|
||||
|
||||
/** @var float */
|
||||
$GCD = MathTrig\Gcd::evaluate($decimalPart, $decimalDivisor);
|
||||
/** @var float */
|
||||
$decimalPartx = $decimalPart;
|
||||
|
||||
$adjustedDecimalPart = $decimalPart / $GCD;
|
||||
$adjustedDecimalPart = $decimalPartx / $GCD;
|
||||
$adjustedDecimalDivisor = $decimalDivisor / $GCD;
|
||||
|
||||
if ((strpos($format, '0') !== false)) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
|
|||
// */
|
||||
class Worksheet extends BIFFwriter
|
||||
{
|
||||
/** @var int */
|
||||
private static $always0 = 0;
|
||||
|
||||
/** @var int */
|
||||
private static $always1 = 1;
|
||||
|
||||
/**
|
||||
* Formula parser.
|
||||
*
|
||||
|
|
@ -2923,11 +2929,11 @@ class Worksheet extends BIFFwriter
|
|||
$flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0);
|
||||
$flags |= (1 == $bTxRotation ? 0x00000008 : 0);
|
||||
// Justify last line flag
|
||||
$flags |= (1 == 1 ? 0x00000010 : 0);
|
||||
$flags |= (1 == self::$always1 ? 0x00000010 : 0);
|
||||
$flags |= (1 == $bIndent ? 0x00000020 : 0);
|
||||
$flags |= (1 == $bShrinkToFit ? 0x00000040 : 0);
|
||||
// Default
|
||||
$flags |= (1 == 1 ? 0x00000080 : 0);
|
||||
$flags |= (1 == self::$always1 ? 0x00000080 : 0);
|
||||
// Protection
|
||||
$flags |= (1 == $bProtLocked ? 0x00000100 : 0);
|
||||
$flags |= (1 == $bProtHidden ? 0x00000200 : 0);
|
||||
|
|
@ -2936,13 +2942,13 @@ class Worksheet extends BIFFwriter
|
|||
$flags |= (1 == $bBorderRight ? 0x00000800 : 0);
|
||||
$flags |= (1 == $bBorderTop ? 0x00001000 : 0);
|
||||
$flags |= (1 == $bBorderBottom ? 0x00002000 : 0);
|
||||
$flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border
|
||||
$flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border
|
||||
$flags |= (1 == self::$always1 ? 0x00004000 : 0); // Top left to Bottom right border
|
||||
$flags |= (1 == self::$always1 ? 0x00008000 : 0); // Bottom left to Top right border
|
||||
// Pattern
|
||||
$flags |= (1 == $bFillStyle ? 0x00010000 : 0);
|
||||
$flags |= (1 == $bFillColor ? 0x00020000 : 0);
|
||||
$flags |= (1 == $bFillColorBg ? 0x00040000 : 0);
|
||||
$flags |= (1 == 1 ? 0x00380000 : 0);
|
||||
$flags |= (1 == self::$always1 ? 0x00380000 : 0);
|
||||
// Font
|
||||
$flags |= (1 == $bFormatFont ? 0x04000000 : 0);
|
||||
// Alignment:
|
||||
|
|
@ -2954,7 +2960,7 @@ class Worksheet extends BIFFwriter
|
|||
// Protection
|
||||
$flags |= (1 == $bFormatProt ? 0x40000000 : 0);
|
||||
// Text direction
|
||||
$flags |= (1 == 0 ? 0x80000000 : 0);
|
||||
$flags |= (1 == self::$always0 ? 0x80000000 : 0);
|
||||
|
||||
$dataBlockFont = null;
|
||||
$dataBlockAlign = null;
|
||||
|
|
@ -3040,10 +3046,10 @@ class Worksheet extends BIFFwriter
|
|||
$optionsFlags = 0;
|
||||
$optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() === null ? 1 : 0);
|
||||
$optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0);
|
||||
$optionsFlags |= (1 == 1 ? 0x00000008 : 0);
|
||||
$optionsFlags |= (1 == 1 ? 0x00000010 : 0);
|
||||
$optionsFlags |= (1 == 0 ? 0x00000020 : 0);
|
||||
$optionsFlags |= (1 == 1 ? 0x00000080 : 0);
|
||||
$optionsFlags |= (1 == self::$always1 ? 0x00000008 : 0);
|
||||
$optionsFlags |= (1 == self::$always1 ? 0x00000010 : 0);
|
||||
$optionsFlags |= (1 == self::$always0 ? 0x00000020 : 0);
|
||||
$optionsFlags |= (1 == self::$always1 ? 0x00000080 : 0);
|
||||
$dataBlockFont .= pack('V', $optionsFlags);
|
||||
// Escapement type
|
||||
$dataBlockFont .= pack('V', $fontEscapement);
|
||||
|
|
|
|||
Loading…
Reference in New Issue