diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist
index 3eafb6ca1..ba381a28f 100644
--- a/.phpcs.xml.dist
+++ b/.phpcs.xml.dist
@@ -5,6 +5,7 @@
samples
src
tests
+ infra
samples/Header.php
*/tests/Core/*/*Test\.(inc|css|js)$
diff --git a/infra/DocumentGenerator.php b/infra/DocumentGenerator.php
index e2c3c86cb..5a86d1778 100644
--- a/infra/DocumentGenerator.php
+++ b/infra/DocumentGenerator.php
@@ -52,7 +52,7 @@ class DocumentGenerator
return rtrim($result, ' ');
}
- private static function getPhpSpreadsheetFunctionText($functionCall): string
+ private static function getPhpSpreadsheetFunctionText(mixed $functionCall): string
{
if (is_string($functionCall)) {
return $functionCall;
diff --git a/infra/LocaleGenerator.php b/infra/LocaleGenerator.php
index 5e570f7f0..508a6480e 100644
--- a/infra/LocaleGenerator.php
+++ b/infra/LocaleGenerator.php
@@ -38,32 +38,32 @@ class LocaleGenerator
*/
protected $translationBaseFolder;
- protected $phpSpreadsheetFunctions;
+ protected array $phpSpreadsheetFunctions;
/**
* @var Spreadsheet
*/
protected $translationSpreadsheet;
- protected $verbose;
+ protected bool $verbose;
/**
* @var Worksheet
*/
protected $localeTranslations;
- protected $localeLanguageMap = [];
+ protected array $localeLanguageMap = [];
- protected $errorCodeMap = [];
+ protected array $errorCodeMap = [];
/**
* @var Worksheet
*/
private $functionNameTranslations;
- protected $functionNameLanguageMap = [];
+ protected array $functionNameLanguageMap = [];
- protected $functionNameMap = [];
+ protected array $functionNameMap = [];
public function __construct(
string $translationBaseFolder,
@@ -98,7 +98,7 @@ class LocaleGenerator
}
}
- protected function buildConfigFileForLocale($column, $locale): void
+ protected function buildConfigFileForLocale(string $column, string $locale): void
{
$language = $this->localeTranslations->getCell($column . self::ENGLISH_LANGUAGE_NAME_ROW)->getValue();
$localeLanguage = $this->localeTranslations->getCell($column . self::LOCALE_LANGUAGE_NAME_ROW)->getValue();
@@ -124,7 +124,8 @@ class LocaleGenerator
fclose($configFile);
}
- protected function writeConfigArgumentSeparator($configFile, $column): void
+ /** @param resource $configFile resource to write to */
+ protected function writeConfigArgumentSeparator($configFile, string $column): void
{
$translationCell = $this->localeTranslations->getCell($column . self::ARGUMENT_SEPARATOR_ROW);
$localeValue = $translationCell->getValue();
@@ -136,7 +137,8 @@ class LocaleGenerator
}
}
- protected function writeConfigCurrencySymbol($configFile, $column): void
+ /** @param resource $configFile resource to write to */
+ protected function writeConfigCurrencySymbol($configFile, string $column): void
{
$translationCell = $this->localeTranslations->getCell($column . self::CURRENCY_SYMBOL_ROW);
$localeValue = $translationCell->getValue();
@@ -151,7 +153,7 @@ class LocaleGenerator
}
}
- protected function buildFunctionsFileForLocale($column, $locale): void
+ protected function buildFunctionsFileForLocale(string $column, string $locale): void
{
$language = $this->functionNameTranslations->getCell($column . self::ENGLISH_LANGUAGE_NAME_ROW)->getValue();
$localeLanguage = $this->functionNameTranslations->getCell($column . self::LOCALE_LANGUAGE_NAME_ROW)
@@ -176,6 +178,7 @@ class LocaleGenerator
fclose($functionFile);
}
+ /** @return resource used by other methods in this class */
protected function openConfigFile(string $locale, string $language, string $localeLanguage)
{
$this->log("Building locale {$locale} ($language) configuration");
@@ -185,11 +188,15 @@ class LocaleGenerator
$this->log("Writing locale configuration to {$configFileName}");
$configFile = fopen($configFileName, 'wb');
+ if ($configFile === false) {
+ throw new Exception('Unable to open $configFileName for write');
+ }
$this->writeFileHeader($configFile, $localeLanguage, $language, 'locale settings');
return $configFile;
}
+ /** @return resource used by other methods in this class */
protected function openFunctionNameFile(string $locale, string $language, string $localeLanguage)
{
$this->log("Building locale {$locale} ($language) function names");
@@ -199,6 +206,9 @@ class LocaleGenerator
$this->log("Writing local function names to {$functionFileName}");
$functionFile = fopen($functionFileName, 'wb');
+ if ($functionFile === false) {
+ throw new Exception('Unable to open $functionFileName for write');
+ }
$this->writeFileHeader($functionFile, $localeLanguage, $language, 'function name translations');
return $functionFile;
@@ -218,6 +228,7 @@ class LocaleGenerator
return $localeFolder;
}
+ /** @param resource $localeFile file being written to */
protected function writeFileHeader($localeFile, string $localeLanguage, string $language, string $title): void
{
fwrite($localeFile, str_repeat('#', 60) . self::EOL);
@@ -229,6 +240,7 @@ class LocaleGenerator
fwrite($localeFile, str_repeat('#', 60) . self::EOL . self::EOL);
}
+ /** @param resource $localeFile file being written to */
protected function writeFileSectionHeader($localeFile, string $header): void
{
fwrite($localeFile, self::EOL . '##' . self::EOL);
@@ -245,9 +257,6 @@ class LocaleGenerator
protected function getTranslationSheet(string $sheetName): Worksheet
{
$worksheet = $this->translationSpreadsheet->setActiveSheetIndexByName($sheetName);
- if ($worksheet === null) {
- throw new Exception("{$sheetName} Worksheet not found");
- }
return $worksheet;
}
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index f6ce123ad..154541708 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -8,6 +8,8 @@ parameters:
paths:
- src/
- tests/
+ - samples/
+ - infra/
excludePaths:
- src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
- src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php
@@ -21,3 +23,4 @@ parameters:
ignoreErrors:
# Accept a bit anything for assert methods
- '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~'
+ - '~^Variable \$helper might not be defined\.$~'
diff --git a/samples/Autofilter/10_Autofilter_selection_2.php b/samples/Autofilter/10_Autofilter_selection_2.php
index 4d5d891cf..6b82bcdf5 100644
--- a/samples/Autofilter/10_Autofilter_selection_2.php
+++ b/samples/Autofilter/10_Autofilter_selection_2.php
@@ -126,7 +126,7 @@ $helper->log('Set country code filter (Column C) to "Germany"');
$autoFilter->getColumn('D')
->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER)
->createRule()
- ->setRule(Rule::AUTOFILTER_COLUMN_RULE_EQUAL, null, Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE)
+ ->setRule(Rule::AUTOFILTER_COLUMN_RULE_EQUAL, '', Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE)
->setRuleType(Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
$helper->log('Add filter on the Date (Column D) to display year to date');
diff --git a/samples/Basic/02_Types.php b/samples/Basic/02_Types.php
index 4eaaa8b15..d28af579d 100644
--- a/samples/Basic/02_Types.php
+++ b/samples/Basic/02_Types.php
@@ -109,9 +109,9 @@ $richText = new RichText();
$richText->createText('你好 ');
$payable = $richText->createTextRun('你 好 吗?');
-$payable->getFont()->setBold(true);
-$payable->getFont()->setItalic(true);
-$payable->getFont()->setColor(new Color(Color::COLOR_DARKGREEN));
+$payable->getFontOrThrow()->setBold(true);
+$payable->getFontOrThrow()->setItalic(true);
+$payable->getFontOrThrow()->setColor(new Color(Color::COLOR_DARKGREEN));
$richText->createText(', unless specified otherwise on the invoice.');
@@ -123,7 +123,7 @@ $richText2 = new RichText();
$richText2->createText("black text\n");
$red = $richText2->createTextRun('red text');
-$red->getFont()->setColor(new Color(Color::COLOR_RED));
+$red->getFontOrThrow()->setColor(new Color(Color::COLOR_RED));
$spreadsheet->getActiveSheet()
->getCell('C14')
diff --git a/samples/Basic/19_Namedrange.php b/samples/Basic/19_Namedrange.php
index 6170fa28e..5b1a25270 100644
--- a/samples/Basic/19_Namedrange.php
+++ b/samples/Basic/19_Namedrange.php
@@ -36,6 +36,9 @@ $spreadsheet->addNamedRange(new NamedRange('PersonLN', $spreadsheet->getActiveSh
// Rename named ranges
$helper->log('Rename named ranges');
+if ($spreadsheet->getNamedRange('PersonName') === null) {
+ throw new Exception('named range not found');
+}
$spreadsheet->getNamedRange('PersonName')->setName('PersonFN');
// Rename worksheet
diff --git a/samples/Basic/25_In_memory_image.php b/samples/Basic/25_In_memory_image.php
index 1833e683a..7ba4871b3 100644
--- a/samples/Basic/25_In_memory_image.php
+++ b/samples/Basic/25_In_memory_image.php
@@ -27,12 +27,15 @@ $spreadsheet->getProperties()->setCreator('Maarten Balliauw')
// Generate an image
$helper->log('Generate an image');
-$gdImage = @imagecreatetruecolor(120, 20);
+$gdImage = imagecreatetruecolor(120, 20);
if (!$gdImage) {
- exit('Cannot Initialize new GD image stream');
+ throw new Exception('Cannot Initialize new GD image stream');
}
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
+if ($textColor === false) {
+ throw new Exception('imagecolorallocate failed');
+}
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
// Add a drawing to the worksheet
diff --git a/samples/Basic/39_Dropdown.php b/samples/Basic/39_Dropdown.php
index 0e8ff52b6..232ed0eda 100644
--- a/samples/Basic/39_Dropdown.php
+++ b/samples/Basic/39_Dropdown.php
@@ -20,7 +20,8 @@ $spreadsheet->getProperties()
->setDescription('Test document for PhpSpreadsheet, generated using PHP classes.')
->setKeywords('Office PhpSpreadsheet php')
->setCategory('Test result file');
-function transpose($value)
+
+function transpose(string $value): array
{
return [$value];
}
@@ -30,12 +31,12 @@ $continentColumn = 'D';
$column = 'F';
// Set data for dropdowns
-$continents = glob(__DIR__ . '/data/continents/*');
+$continents = glob(__DIR__ . '/data/continents/*') ?: [];
foreach ($continents as $key => $filename) {
$continent = pathinfo($filename, PATHINFO_FILENAME);
$helper->log("Loading $continent");
$continent = str_replace(' ', '_', $continent);
- $countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ $countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [];
$countryCount = count($countries);
// Transpose $countries from a row to a column array
diff --git a/samples/Calculations/Engineering/Convert-Online.php b/samples/Calculations/Engineering/Convert-Online.php
index e20e4c79b..3d26a3f6b 100644
--- a/samples/Calculations/Engineering/Convert-Online.php
+++ b/samples/Calculations/Engineering/Convert-Online.php
@@ -77,6 +77,7 @@ if (isset($_POST['submit'])) {
$quantity = $_POST['quantity'];
$fromUnit = $_POST['fromUnit'];
$toUnit = $_POST['toUnit'];
+ /** @var float|string */
$result = ConvertUOM::CONVERT($quantity, $fromUnit, $toUnit);
echo "{$quantity} {$units[$_POST['category']][$fromUnit]} is {$result} {$units[$_POST['category']][$toUnit]}", PHP_EOL;
diff --git a/samples/Chart/32_Chart_read_write.php b/samples/Chart/32_Chart_read_write.php
index 42944c0cc..900c9567c 100644
--- a/samples/Chart/32_Chart_read_write.php
+++ b/samples/Chart/32_Chart_read_write.php
@@ -13,7 +13,7 @@ if ((isset($argc)) && ($argc > 1)) {
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
}
} else {
- $inputFileNames = glob($inputFileNames);
+ $inputFileNames = glob($inputFileNames) ?: [];
}
foreach ($inputFileNames as $inputFileName) {
$inputFileNameShort = basename($inputFileName);
@@ -40,7 +40,7 @@ foreach ($inputFileNames as $inputFileName) {
} else {
natsort($chartNames);
foreach ($chartNames as $i => $chartName) {
- $chart = $worksheet->getChartByName($chartName);
+ $chart = $worksheet->getChartByNameOrThrow($chartName);
if ($chart->getTitle() !== null) {
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
} else {
@@ -48,15 +48,15 @@ foreach ($inputFileNames as $inputFileName) {
}
$helper->log(' ' . $chartName . ' - ' . $caption);
$indentation = str_repeat(' ', strlen($chartName) + 3);
- $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ $groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
if ($groupCount == 1) {
- $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ $chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
$helper->log($indentation . ' ' . $chartType);
$helper->renderChart($chart, __FILE__);
} else {
$chartTypes = [];
for ($i = 0; $i < $groupCount; ++$i) {
- $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ $chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
}
$chartTypes = array_unique($chartTypes);
if (count($chartTypes) == 1) {
diff --git a/samples/Chart/32_Chart_read_write_HTML.php b/samples/Chart/32_Chart_read_write_HTML.php
index 3cb377873..0dc5484ce 100644
--- a/samples/Chart/32_Chart_read_write_HTML.php
+++ b/samples/Chart/32_Chart_read_write_HTML.php
@@ -18,7 +18,7 @@ if ((isset($argc)) && ($argc > 1)) {
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
}
} else {
- $inputFileNames = glob($inputFileNames);
+ $inputFileNames = glob($inputFileNames) ?: [];
}
foreach ($inputFileNames as $inputFileName) {
$inputFileNameShort = basename($inputFileName);
@@ -46,22 +46,22 @@ foreach ($inputFileNames as $inputFileName) {
} else {
natsort($chartNames);
foreach ($chartNames as $i => $chartName) {
- $chart = $worksheet->getChartByName($chartName);
+ $chart = $worksheet->getChartByNameOrThrow($chartName);
if ($chart->getTitle() !== null) {
- $caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
+ $caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
} else {
$caption = 'Untitled';
}
$helper->log(' ' . $chartName . ' - ' . $caption);
$helper->log(str_repeat(' ', strlen($chartName) + 3));
- $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ $groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
if ($groupCount == 1) {
- $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ $chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
$helper->log(' ' . $chartType);
} else {
$chartTypes = [];
for ($i = 0; $i < $groupCount; ++$i) {
- $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ $chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
}
$chartTypes = array_unique($chartTypes);
if (count($chartTypes) == 1) {
diff --git a/samples/Chart/32_Chart_read_write_PDF.php b/samples/Chart/32_Chart_read_write_PDF.php
index e3d702a9d..0ac41f71f 100644
--- a/samples/Chart/32_Chart_read_write_PDF.php
+++ b/samples/Chart/32_Chart_read_write_PDF.php
@@ -20,7 +20,7 @@ if ((isset($argc)) && ($argc > 1)) {
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
}
} else {
- $inputFileNames = glob($inputFileNames);
+ $inputFileNames = glob($inputFileNames) ?: [];
}
foreach ($inputFileNames as $inputFileName) {
$inputFileNameShort = basename($inputFileName);
@@ -48,22 +48,22 @@ foreach ($inputFileNames as $inputFileName) {
} else {
natsort($chartNames);
foreach ($chartNames as $i => $chartName) {
- $chart = $worksheet->getChartByName($chartName);
+ $chart = $worksheet->getChartByNameOrThrow($chartName);
if ($chart->getTitle() !== null) {
- $caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
+ $caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
} else {
$caption = 'Untitled';
}
$helper->log(' ' . $chartName . ' - ' . $caption);
$helper->log(str_repeat(' ', strlen($chartName) + 3));
- $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ $groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
if ($groupCount == 1) {
- $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ $chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
$helper->log(' ' . $chartType);
} else {
$chartTypes = [];
for ($i = 0; $i < $groupCount; ++$i) {
- $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ $chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
}
$chartTypes = array_unique($chartTypes);
if (count($chartTypes) == 1) {
diff --git a/samples/Chart/33_Chart_create_line_dateaxis.php b/samples/Chart/33_Chart_create_line_dateaxis.php
index d7b674f6d..c177de79a 100644
--- a/samples/Chart/33_Chart_create_line_dateaxis.php
+++ b/samples/Chart/33_Chart_create_line_dateaxis.php
@@ -195,7 +195,7 @@ $spreadsheet->createSheet();
$chartSheet = $spreadsheet->getSheet(1);
$chartSheet->setTitle('Scatter+Line Chart');
-$chartSheet = $spreadsheet->getSheetByName('Scatter+Line Chart');
+$chartSheet = $spreadsheet->getSheetByNameOrThrow('Scatter+Line Chart');
// Add the chart to the worksheet
$chartSheet->addChart($chart);
@@ -340,11 +340,14 @@ $spreadsheet->disconnectWorksheets();
function dateRange(int $nrows, Spreadsheet $wrkbk): array
{
- $dataSheet = $wrkbk->getSheetByName('Data');
+ $dataSheet = $wrkbk->getSheetByNameOrThrow('Data');
// start the xaxis at the beginning of the quarter of the first date
$startDateStr = $dataSheet->getCell('B2')->getValue(); // yyyy-mm-dd date string
$startDate = DateTime::createFromFormat('Y-m-d', $startDateStr); // php date obj
+ if ($startDate === false) {
+ throw new Exception("invalid start date $startDateStr on spreadsheet");
+ }
// get date of first day of the quarter of the start date
$startMonth = (int) $startDate->format('n'); // suppress leading zero
@@ -357,12 +360,19 @@ function dateRange(int $nrows, Spreadsheet $wrkbk): array
// end the xaxis at the end of the quarter of the last date
$lastDateStr = $dataSheet->getCell([2, $nrows + 1])->getValue();
$lastDate = DateTime::createFromFormat('Y-m-d', $lastDateStr);
+ if ($lastDate === false) {
+ throw new Exception("invalid last date $lastDateStr on spreadsheet");
+ }
$lastMonth = (int) $lastDate->format('n');
$lastYr = (int) $lastDate->format('Y');
$qtr = intdiv($lastMonth, 3) + (($lastMonth % 3 > 0) ? 1 : 0);
$qtrEndMonth = 3 + (($qtr - 1) * 3);
$qtrEndMonth = sprintf('%02d', $qtrEndMonth);
- $lastDOM = DateTime::createFromFormat('Y-m-d', "$lastYr-$qtrEndMonth-01")->format('t');
+ $lastDOMDate = DateTime::createFromFormat('Y-m-d', "$lastYr-$qtrEndMonth-01");
+ if ($lastDOMDate === false) {
+ throw new Exception("invalid last dom date $lastYr-$qtrEndMonth-01 on spreadsheet");
+ }
+ $lastDOM = $lastDOMDate->format('t');
$qtrEndStr = "$lastYr-$qtrEndMonth-$lastDOM";
$ExcelQtrEndDateVal = SharedDate::convertIsoDate($qtrEndStr);
diff --git a/samples/Chart/33_Chart_create_scatter5_trendlines.php b/samples/Chart/33_Chart_create_scatter5_trendlines.php
index f58aadaf7..7467c8206 100644
--- a/samples/Chart/33_Chart_create_scatter5_trendlines.php
+++ b/samples/Chart/33_Chart_create_scatter5_trendlines.php
@@ -169,7 +169,7 @@ $spreadsheet->createSheet();
$chartSheet = $spreadsheet->getSheet(1);
$chartSheet->setTitle('Scatter Chart');
-$chartSheet = $spreadsheet->getSheetByName('Scatter Chart');
+$chartSheet = $spreadsheet->getSheetByNameOrThrow('Scatter Chart');
// Add the chart to the worksheet
$chartSheet->addChart($chart);
diff --git a/samples/Chart/35_Chart_render.php b/samples/Chart/35_Chart_render.php
index 4c403d993..57eb691ef 100644
--- a/samples/Chart/35_Chart_render.php
+++ b/samples/Chart/35_Chart_render.php
@@ -19,11 +19,13 @@ if ((isset($argc)) && ($argc > 1)) {
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
}
} else {
- $inputFileNames = glob($inputFileNames);
+ $inputFileNames = glob($inputFileNames) ?: [];
}
if (count($inputFileNames) === 1) {
+ /** @var string[] */
$unresolvedErrors = [];
} else {
+ /** @var string[] */
$unresolvedErrors = [
// The following spreadsheet was created by 3rd party software,
// and doesn't include the data that usually accompanies a chart.
@@ -66,9 +68,9 @@ foreach ($inputFileNames as $inputFileName) {
natsort($chartNames);
foreach ($chartNames as $j => $chartName) {
$i = $renderedCharts + $j;
- $chart = $worksheet->getChartByName($chartName);
+ $chart = $worksheet->getChartByNameOrThrow($chartName);
if ($chart->getTitle() !== null) {
- $caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
+ $caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
} else {
$caption = 'Untitled';
}
diff --git a/samples/Chart/35_Chart_render33.php b/samples/Chart/35_Chart_render33.php
index 97091fcee..f9c7c11ad 100644
--- a/samples/Chart/35_Chart_render33.php
+++ b/samples/Chart/35_Chart_render33.php
@@ -10,7 +10,7 @@ require __DIR__ . '/../Header.php';
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class);
$inputFileType = 'Xlsx';
-$inputFileNames = $helper->getTemporaryFolder() . '/33_Chart_create_*.xlsx';
+$inputFileNamesString = $helper->getTemporaryFolder() . '/33_Chart_create_*.xlsx';
if ((isset($argc)) && ($argc > 1)) {
$inputFileNames = [];
@@ -18,11 +18,13 @@ if ((isset($argc)) && ($argc > 1)) {
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
}
} else {
- $inputFileNames = glob($inputFileNames);
+ $inputFileNames = glob($inputFileNamesString) ?: [];
}
if (count($inputFileNames) === 1) {
+ /** @var string[] */
$unresolvedErrors = [];
} else {
+ /** @var string[] */
$unresolvedErrors = [
//'33_Chart_create_bar_stacked.xlsx', // fixed with mitoteam/jpgraph 10.3
];
@@ -62,9 +64,9 @@ foreach ($inputFileNames as $inputFileName) {
natsort($chartNames);
foreach ($chartNames as $j => $chartName) {
$i = $renderedCharts + $j;
- $chart = $worksheet->getChartByName($chartName);
+ $chart = $worksheet->getChartByNameOrThrow($chartName);
if ($chart->getTitle() !== null) {
- $caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
+ $caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
} else {
$caption = 'Untitled';
}
diff --git a/samples/Chart/37_Chart_dynamic_title.php b/samples/Chart/37_Chart_dynamic_title.php
index b8b801faa..e0df17cd0 100644
--- a/samples/Chart/37_Chart_dynamic_title.php
+++ b/samples/Chart/37_Chart_dynamic_title.php
@@ -37,7 +37,7 @@ foreach ($inputFileNames as $inputFileName) {
} else {
natsort($chartNames);
foreach ($chartNames as $i => $chartName) {
- $chart = $worksheet->getChartByName($chartName);
+ $chart = $worksheet->getChartByNameOrThrow($chartName);
if ($chart->getTitle() !== null) {
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
} else {
@@ -45,15 +45,15 @@ foreach ($inputFileNames as $inputFileName) {
}
$helper->log(' ' . $chartName . ' - ' . $caption);
$indentation = str_repeat(' ', strlen($chartName) + 3);
- $groupCount = $chart->getPlotArea()->getPlotGroupCount();
+ $groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
if ($groupCount == 1) {
- $chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
+ $chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
$helper->log($indentation . ' ' . $chartType);
$helper->renderChart($chart, __FILE__, $spreadsheet);
} else {
$chartTypes = [];
for ($i = 0; $i < $groupCount; ++$i) {
- $chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
+ $chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
}
$chartTypes = array_unique($chartTypes);
if (count($chartTypes) == 1) {
diff --git a/samples/DefinedNames/CrossWorksheetNamedFormula.php b/samples/DefinedNames/CrossWorksheetNamedFormula.php
index 5ce765162..6c2faec2b 100644
--- a/samples/DefinedNames/CrossWorksheetNamedFormula.php
+++ b/samples/DefinedNames/CrossWorksheetNamedFormula.php
@@ -40,7 +40,7 @@ setYearlyData($worksheet, '2020', $data2020);
$worksheet = $spreadsheet->addSheet(new Worksheet($spreadsheet));
setYearlyData($worksheet, '2020', [], 'GROWTH');
-function setYearlyData(Worksheet $worksheet, string $year, $yearlyData, ?string $title = null): void
+function setYearlyData(Worksheet $worksheet, string $year, array $yearlyData, ?string $title = null): void
{
// Set up some basic data
$worksheetTitle = $title ?: $year;
diff --git a/samples/DefinedNames/ScopedNamedRange.php b/samples/DefinedNames/ScopedNamedRange.php
index aa71454df..88bc62777 100644
--- a/samples/DefinedNames/ScopedNamedRange.php
+++ b/samples/DefinedNames/ScopedNamedRange.php
@@ -60,12 +60,18 @@ $worksheet
->setCellValue("B{$row}", '=SUM(COLUMN_DATA_VALUES)')
->setCellValue("C{$row}", '=SUM(COLUMN_DATA_VALUES)');
+$range = $spreadsheet->getNamedRange('CHARGE_RATE');
+if ($range === null || $range->getWorksheet() === null) {
+ throw new Exception('expected named range not found');
+}
+$chargeRateCellValue = $spreadsheet
+ ->getSheetByNameOrThrow($range->getWorksheet()->getTitle())
+ ->getCell($range->getCellsInRange()[0])->getValue();
+
$helper->log(sprintf(
'Worked %.2f hours at a rate of %s - Charge to the client is %.2f',
$worksheet->getCell("B{$row}")->getCalculatedValue(),
- $chargeRateCellValue = $spreadsheet
- ->getSheetByName($spreadsheet->getNamedRange('CHARGE_RATE')->getWorksheet()->getTitle())
- ->getCell($spreadsheet->getNamedRange('CHARGE_RATE')->getCellsInRange()[0])->getValue(),
+ $chargeRateCellValue,
$worksheet->getCell("C{$row}")->getCalculatedValue()
));
diff --git a/samples/Pdf/21b_Pdf.php b/samples/Pdf/21b_Pdf.php
index d7a1cb51e..38ba4d9c4 100644
--- a/samples/Pdf/21b_Pdf.php
+++ b/samples/Pdf/21b_Pdf.php
@@ -21,7 +21,7 @@ function replaceBody(string $html): string
/';
$simulatedBodyStart = Mpdf::SIMULATED_BODY_START;
$bodyrepl = << [
- 'R' => $fontFile,
- ],
- ];
+ 'R' => $fontFile,
+ ],
+ ];
return new \Mpdf\Mpdf($config);
}
diff --git a/samples/Reader/08_Simple_file_reader_loading_several_named_worksheets.php b/samples/Reader/08_Simple_file_reader_loading_several_named_worksheets.php
index 66efc3e0f..0a79dadd9 100644
--- a/samples/Reader/08_Simple_file_reader_loading_several_named_worksheets.php
+++ b/samples/Reader/08_Simple_file_reader_loading_several_named_worksheets.php
@@ -4,9 +4,15 @@ use PhpOffice\PhpSpreadsheet\IOFactory;
require __DIR__ . '/../Header.php';
+/** @return string[] */
+function getDesiredSheetNames(): array
+{
+ return ['Data Sheet #1', 'Data Sheet #3'];
+}
+
$inputFileType = 'Xls';
$inputFileName = __DIR__ . '/sampleData/example1.xls';
-$sheetnames = ['Data Sheet #1', 'Data Sheet #3'];
+$sheetnames = getDesiredSheetNames();
$helper->log('Loading file ' . pathinfo($inputFileName, PATHINFO_BASENAME) . ' using IOFactory with a defined reader type of ' . $inputFileType);
$reader = IOFactory::createReader($inputFileType);
diff --git a/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php b/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php
index 437fe6cff..a8148f33c 100644
--- a/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php
+++ b/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php
@@ -13,13 +13,13 @@ $sheetname = 'Data Sheet #3';
class MyReadFilter implements IReadFilter
{
- private $startRow = 0;
+ private int $startRow = 0;
- private $endRow = 0;
+ private int $endRow = 0;
- private $columns = [];
+ private array $columns = [];
- public function __construct($startRow, $endRow, $columns)
+ public function __construct(int $startRow, int $endRow, array $columns)
{
$this->startRow = $startRow;
$this->endRow = $endRow;
diff --git a/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php b/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php
index ec0113261..64c5b5665 100644
--- a/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php
+++ b/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php
@@ -13,17 +13,14 @@ $inputFileName = __DIR__ . '/sampleData/example2.xls';
/** Define a Read Filter class implementing IReadFilter */
class ChunkReadFilter implements IReadFilter
{
- private $startRow = 0;
+ private int $startRow = 0;
- private $endRow = 0;
+ private int $endRow = 0;
/**
* We expect a list of the rows that we want to read to be passed into the constructor.
- *
- * @param mixed $startRow
- * @param mixed $chunkSize
*/
- public function __construct($startRow, $chunkSize)
+ public function __construct(int $startRow, int $chunkSize)
{
$this->startRow = $startRow;
$this->endRow = $startRow + $chunkSize;
diff --git a/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php b/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php
index e8c4a6590..5b2a4e48f 100644
--- a/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php
+++ b/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php
@@ -13,17 +13,14 @@ $inputFileName = __DIR__ . '/sampleData/example2.xls';
/** Define a Read Filter class implementing IReadFilter */
class ChunkReadFilter implements IReadFilter
{
- private $startRow = 0;
+ private int $startRow = 0;
- private $endRow = 0;
+ private int $endRow = 0;
/**
* Set the list of rows that we want to read.
- *
- * @param mixed $startRow
- * @param mixed $chunkSize
*/
- public function setRows($startRow, $chunkSize): void
+ public function setRows(int $startRow, int $chunkSize): void
{
$this->startRow = $startRow;
$this->endRow = $startRow + $chunkSize;
diff --git a/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php b/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php
index 82544f60a..3d6b2cb06 100644
--- a/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php
+++ b/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php
@@ -13,17 +13,14 @@ $inputFileName = __DIR__ . '/sampleData/example2.csv';
/** Define a Read Filter class implementing IReadFilter */
class ChunkReadFilter implements IReadFilter
{
- private $startRow = 0;
+ private int $startRow = 0;
- private $endRow = 0;
+ private int $endRow = 0;
/**
* Set the list of rows that we want to read.
- *
- * @param mixed $startRow
- * @param mixed $chunkSize
*/
- public function setRows($startRow, $chunkSize): void
+ public function setRows(int $startRow, int $chunkSize): void
{
$this->startRow = $startRow;
$this->endRow = $startRow + $chunkSize;
@@ -51,8 +48,8 @@ $chunkFilter = new ChunkReadFilter();
// Tell the Reader that we want to use the Read Filter that we've Instantiated
// and that we want to store it in contiguous rows/columns
-$reader->setReadFilter($chunkFilter)
- ->setContiguous(true);
+$reader->setReadFilter($chunkFilter);
+$reader->setContiguous(true);
// Instantiate a new PhpSpreadsheet object manually
$spreadsheet = new Spreadsheet();
diff --git a/samples/Reader/20_Reader_worksheet_hyperlink_image.php b/samples/Reader/20_Reader_worksheet_hyperlink_image.php
index 2b3f294a6..19200ee21 100644
--- a/samples/Reader/20_Reader_worksheet_hyperlink_image.php
+++ b/samples/Reader/20_Reader_worksheet_hyperlink_image.php
@@ -14,9 +14,12 @@ $aSheet = $spreadsheet->getActiveSheet();
$gdImage = @imagecreatetruecolor(120, 20);
if ($gdImage === false) {
- throw new \Exception('imagecreatetruecolor failed');
+ throw new Exception('imagecreatetruecolor failed');
}
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
+if ($textColor === false) {
+ throw new Exception('imagecolorallocate failed');
+}
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
$baseUrl = 'https://phpspreadsheet.readthedocs.io';
@@ -52,7 +55,7 @@ unlink($filename);
$helper->log('reloaded Spreadsheet');
foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) {
- $helper->log('Read link: ' . $pDrawing->getHyperlink()->getUrl());
+ $helper->log('Read link: ' . ($pDrawing->getHyperlink()?->getUrl() ?? 'none'));
}
$helper->log('end');
diff --git a/samples/Wizards/NumberFormat/Accounting.php b/samples/Wizards/NumberFormat/Accounting.php
index c09c7ca6c..20737e502 100644
--- a/samples/Wizards/NumberFormat/Accounting.php
+++ b/samples/Wizards/NumberFormat/Accounting.php
@@ -83,11 +83,11 @@ $currencies = [
if (isset($_POST['submit'])) {
if (!is_numeric($_POST['number'])) {
$helper->log('The Sample Number Value must be numeric');
- } elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
+ } elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
$helper->log('The Decimal Places value must be positive integer');
} else {
try {
- $wizard = new Wizard\Accounting($_POST['currency'], $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
+ $wizard = new Wizard\Accounting($_POST['currency'], (int) $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
$mask = $wizard->format();
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
$helper->log('
Code:
');
diff --git a/samples/Wizards/NumberFormat/Currency.php b/samples/Wizards/NumberFormat/Currency.php
index 87da38360..313db3194 100644
--- a/samples/Wizards/NumberFormat/Currency.php
+++ b/samples/Wizards/NumberFormat/Currency.php
@@ -83,11 +83,11 @@ $currencies = [
if (isset($_POST['submit'])) {
if (!is_numeric($_POST['number'])) {
$helper->log('The Sample Number Value must be numeric');
- } elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
+ } elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
$helper->log('The Decimal Places value must be positive integer');
} else {
try {
- $wizard = new Wizard\Currency($_POST['currency'], $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
+ $wizard = new Wizard\Currency($_POST['currency'], (int) $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
$mask = $wizard->format();
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
$helper->log('
Code:
');
diff --git a/samples/Wizards/NumberFormat/Number.php b/samples/Wizards/NumberFormat/Number.php
index ab2b2b3f3..274f7904a 100644
--- a/samples/Wizards/NumberFormat/Number.php
+++ b/samples/Wizards/NumberFormat/Number.php
@@ -49,11 +49,11 @@ if ($helper->isCli()) {
if (isset($_POST['submit'])) {
if (!is_numeric($_POST['number'])) {
$helper->log('The Sample Number Value must be numeric');
- } elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
+ } elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
$helper->log('The Decimal Places value must be positive integer');
} else {
try {
- $wizard = new Wizard\Number($_POST['decimals'], isset($_POST['thousands']));
+ $wizard = new Wizard\Number((int) $_POST['decimals'], isset($_POST['thousands']));
$mask = $wizard->format();
$example = NumberFormat::toFormattedString((float) $_POST['number'], $mask);
$helper->log('
Code:
');
diff --git a/samples/Wizards/NumberFormat/Percentage.php b/samples/Wizards/NumberFormat/Percentage.php
index c1838827b..71b5c6911 100644
--- a/samples/Wizards/NumberFormat/Percentage.php
+++ b/samples/Wizards/NumberFormat/Percentage.php
@@ -43,11 +43,11 @@ if ($helper->isCli()) {
if (isset($_POST['submit'])) {
if (!is_numeric($_POST['number'])) {
$helper->log('The Sample Number Value must be numeric');
- } elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
+ } elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
$helper->log('The Decimal Places value must be positive integer');
} else {
try {
- $wizard = new Wizard\Percentage($_POST['decimals']);
+ $wizard = new Wizard\Percentage((int) $_POST['decimals']);
$mask = $wizard->format();
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
$helper->log('
Code:
');
diff --git a/samples/Wizards/NumberFormat/Scientific.php b/samples/Wizards/NumberFormat/Scientific.php
index 40d390a5e..61e635d78 100644
--- a/samples/Wizards/NumberFormat/Scientific.php
+++ b/samples/Wizards/NumberFormat/Scientific.php
@@ -43,11 +43,11 @@ if ($helper->isCli()) {
if (isset($_POST['submit'])) {
if (!is_numeric($_POST['number'])) {
$helper->log('The Sample Number Value must be numeric');
- } elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
+ } elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
$helper->log('The Decimal Places value must be positive integer');
} else {
try {
- $wizard = new Wizard\Scientific($_POST['decimals']);
+ $wizard = new Wizard\Scientific((int) $_POST['decimals']);
$mask = $wizard->format();
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
$helper->log('
Code:
');
diff --git a/samples/templates/sampleSpreadsheet.php b/samples/templates/sampleSpreadsheet.php
index 92e88262d..998f21105 100644
--- a/samples/templates/sampleSpreadsheet.php
+++ b/samples/templates/sampleSpreadsheet.php
@@ -74,19 +74,19 @@ $helper->log('Add comments');
$spreadsheet->getActiveSheet()->getComment('E11')->setAuthor('PhpSpreadsheet');
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('PhpSpreadsheet:');
-$commentRichText->getFont()->setBold(true);
+$commentRichText->getFontOrThrow()->setBold(true);
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');
$spreadsheet->getActiveSheet()->getComment('E12')->setAuthor('PhpSpreadsheet');
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('PhpSpreadsheet:');
-$commentRichText->getFont()->setBold(true);
+$commentRichText->getFontOrThrow()->setBold(true);
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('Total amount of VAT on the current invoice.');
$spreadsheet->getActiveSheet()->getComment('E13')->setAuthor('PhpSpreadsheet');
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('PhpSpreadsheet:');
-$commentRichText->getFont()->setBold(true);
+$commentRichText->getFontOrThrow()->setBold(true);
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('Total amount on the current invoice, including VAT.');
$spreadsheet->getActiveSheet()->getComment('E13')->setWidth('100pt');
@@ -100,9 +100,9 @@ $richText = new RichText();
$richText->createText('This invoice is ');
$payable = $richText->createTextRun('payable within thirty days after the end of the month');
-$payable->getFont()->setBold(true);
-$payable->getFont()->setItalic(true);
-$payable->getFont()->setColor(new Color(Color::COLOR_DARKGREEN));
+$payable->getFontOrThrow()->setBold(true);
+$payable->getFontOrThrow()->setItalic(true);
+$payable->getFontOrThrow()->setColor(new Color(Color::COLOR_DARKGREEN));
$richText->createText(', unless specified otherwise on the invoice.');
diff --git a/samples/templates/sampleSpreadsheet2.php b/samples/templates/sampleSpreadsheet2.php
index 5a7beda70..76b5e0454 100644
--- a/samples/templates/sampleSpreadsheet2.php
+++ b/samples/templates/sampleSpreadsheet2.php
@@ -74,19 +74,19 @@ $helper->log('Add comments');
$spreadsheet->getActiveSheet()->getComment('E11')->setAuthor('PhpSpreadsheet');
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('PhpSpreadsheet:');
-$commentRichText->getFont()->setBold(true);
+$commentRichText->getFontOrThrow()->setBold(true);
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');
$spreadsheet->getActiveSheet()->getComment('E12')->setAuthor('PhpSpreadsheet');
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('PhpSpreadsheet:');
-$commentRichText->getFont()->setBold(true);
+$commentRichText->getFontOrThrow()->setBold(true);
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('Total amount of VAT on the current invoice.');
$spreadsheet->getActiveSheet()->getComment('E13')->setAuthor('PhpSpreadsheet');
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('PhpSpreadsheet:');
-$commentRichText->getFont()->setBold(true);
+$commentRichText->getFontOrThrow()->setBold(true);
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun("\r\n");
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('Total amount on the current invoice, including VAT.');
$spreadsheet->getActiveSheet()->getComment('E13')->setWidth('100pt');
@@ -100,9 +100,9 @@ $richText = new RichText();
$richText->createText('This invoice is ');
$payable = $richText->createTextRun('payable within thirty days after the end of the month');
-$payable->getFont()->setBold(true);
-$payable->getFont()->setItalic(true);
-$payable->getFont()->setColor(new Color(Color::COLOR_DARKGREEN));
+$payable->getFontOrThrow()->setBold(true);
+$payable->getFontOrThrow()->setItalic(true);
+$payable->getFontOrThrow()->setColor(new Color(Color::COLOR_DARKGREEN));
$richText->createText(', unless specified otherwise on the invoice.');
diff --git a/src/PhpSpreadsheet/Cell/DataValidation.php b/src/PhpSpreadsheet/Cell/DataValidation.php
index 7f1b363c5..22b285b30 100644
--- a/src/PhpSpreadsheet/Cell/DataValidation.php
+++ b/src/PhpSpreadsheet/Cell/DataValidation.php
@@ -140,13 +140,13 @@ class DataValidation
/**
* Set Formula 1.
*
- * @param string $formula
+ * @param float|int|string $formula usually string, but can be number (test for equal)
*
* @return $this
*/
public function setFormula1($formula): static
{
- $this->formula1 = $formula;
+ $this->formula1 = (string) $formula;
return $this;
}
@@ -164,13 +164,13 @@ class DataValidation
/**
* Set Formula 2.
*
- * @param string $formula
+ * @param float|int|string $formula usually string, but can be number (test for equal)
*
* @return $this
*/
public function setFormula2($formula): static
{
- $this->formula2 = $formula;
+ $this->formula2 = (string) $formula;
return $this;
}
diff --git a/src/PhpSpreadsheet/Chart/Axis.php b/src/PhpSpreadsheet/Chart/Axis.php
index 7de219184..3f9249ced 100644
--- a/src/PhpSpreadsheet/Chart/Axis.php
+++ b/src/PhpSpreadsheet/Chart/Axis.php
@@ -124,10 +124,10 @@ class Axis extends Properties
return $this->axisType === self::AXIS_TYPE_DATE || (bool) $this->axisNumber['numeric'];
}
- public function setAxisOption(string $key, ?string $value): void
+ public function setAxisOption(string $key, null|float|int|string $value): void
{
if ($value !== null && $value !== '') {
- $this->axisOptions[$key] = $value;
+ $this->axisOptions[$key] = (string) $value;
}
}
@@ -141,11 +141,11 @@ class Axis extends Properties
?string $axisOrientation = null,
?string $majorTmt = null,
?string $minorTmt = null,
- ?string $minimum = null,
- ?string $maximum = null,
- ?string $majorUnit = null,
- ?string $minorUnit = null,
- ?string $textRotation = null,
+ null|float|int|string $minimum = null,
+ null|float|int|string $maximum = null,
+ null|float|int|string $majorUnit = null,
+ null|float|int|string $minorUnit = null,
+ null|float|int|string $textRotation = null,
?string $hidden = null,
?string $baseTimeUnit = null,
?string $majorTimeUnit = null,
diff --git a/src/PhpSpreadsheet/Chart/Chart.php b/src/PhpSpreadsheet/Chart/Chart.php
index b86b19cdd..2b8de5d51 100644
--- a/src/PhpSpreadsheet/Chart/Chart.php
+++ b/src/PhpSpreadsheet/Chart/Chart.php
@@ -285,6 +285,16 @@ class Chart
return $this->plotArea;
}
+ public function getPlotAreaOrThrow(): PlotArea
+ {
+ $plotArea = $this->getPlotArea();
+ if ($plotArea !== null) {
+ return $plotArea;
+ }
+
+ throw new Exception('Chart has no PlotArea');
+ }
+
/**
* Set Plot Area.
*/
diff --git a/src/PhpSpreadsheet/Chart/DataSeries.php b/src/PhpSpreadsheet/Chart/DataSeries.php
index 8bceae071..647579345 100644
--- a/src/PhpSpreadsheet/Chart/DataSeries.php
+++ b/src/PhpSpreadsheet/Chart/DataSeries.php
@@ -124,7 +124,7 @@ class DataSeries
* @param DataSeriesValues[] $plotCategory
* @param DataSeriesValues[] $plotValues
* @param null|string $plotDirection
- * @param bool $smoothLine
+ * @param null|bool $smoothLine null treated as false
* @param null|string $plotStyle
*/
public function __construct($plotType = null, $plotGrouping = null, array $plotOrder = [], array $plotLabel = [], array $plotCategory = [], array $plotValues = [], $plotDirection = null, $smoothLine = false, $plotStyle = null)
@@ -144,7 +144,7 @@ class DataSeries
}
$this->plotCategory = $plotCategory;
- $this->smoothLine = $smoothLine;
+ $this->smoothLine = (bool) $smoothLine;
$this->plotStyle = $plotStyle;
if ($plotDirection === null) {
diff --git a/src/PhpSpreadsheet/Chart/DataSeriesValues.php b/src/PhpSpreadsheet/Chart/DataSeriesValues.php
index a3f5ca0cf..72bbf8103 100644
--- a/src/PhpSpreadsheet/Chart/DataSeriesValues.php
+++ b/src/PhpSpreadsheet/Chart/DataSeriesValues.php
@@ -98,7 +98,7 @@ class DataSeriesValues extends Properties
* @param mixed $dataValues
* @param null|mixed $marker
* @param null|ChartColor|ChartColor[]|string|string[] $fillColor
- * @param string $pointSize
+ * @param int|string $pointSize point size
*/
public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = [], $marker = null, $fillColor = null, $pointSize = '3')
{
diff --git a/src/PhpSpreadsheet/Chart/Properties.php b/src/PhpSpreadsheet/Chart/Properties.php
index 849f56194..740702d12 100644
--- a/src/PhpSpreadsheet/Chart/Properties.php
+++ b/src/PhpSpreadsheet/Chart/Properties.php
@@ -795,9 +795,9 @@ abstract class Properties
* @param string $capType
* @param string $joinType
* @param string $headArrowType
- * @param string $headArrowSize
+ * @param null|int|string $headArrowSize index into ARROW_SIZES array
* @param string $endArrowType
- * @param string $endArrowSize
+ * @param null|int|string $endArrowSize index into ARROW_SIZES array
* @param string $headArrowWidth
* @param string $headArrowLength
* @param string $endArrowWidth
@@ -824,7 +824,7 @@ abstract class Properties
if ($headArrowType !== '') {
$this->lineStyleProperties['arrow']['head']['type'] = $headArrowType;
}
- if (array_key_exists($headArrowSize, self::ARROW_SIZES)) {
+ if (isset(self::ARROW_SIZES[$headArrowSize])) {
$this->lineStyleProperties['arrow']['head']['size'] = $headArrowSize;
$this->lineStyleProperties['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w'];
$this->lineStyleProperties['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len'];
@@ -832,7 +832,7 @@ abstract class Properties
if ($endArrowType !== '') {
$this->lineStyleProperties['arrow']['end']['type'] = $endArrowType;
}
- if (array_key_exists($endArrowSize, self::ARROW_SIZES)) {
+ if (isset(self::ARROW_SIZES[$endArrowSize])) {
$this->lineStyleProperties['arrow']['end']['size'] = $endArrowSize;
$this->lineStyleProperties['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w'];
$this->lineStyleProperties['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len'];
diff --git a/src/PhpSpreadsheet/RichText/Run.php b/src/PhpSpreadsheet/RichText/Run.php
index c2b7156e6..05d90579e 100644
--- a/src/PhpSpreadsheet/RichText/Run.php
+++ b/src/PhpSpreadsheet/RichText/Run.php
@@ -2,6 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\RichText;
+use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\Style\Font;
class Run extends TextElement implements ITextElement
@@ -35,6 +36,15 @@ class Run extends TextElement implements ITextElement
return $this->font;
}
+ public function getFontOrThrow(): Font
+ {
+ if ($this->font === null) {
+ throw new SpreadsheetException('unexpected null font');
+ }
+
+ return $this->font;
+ }
+
/**
* Set font.
*
diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php
index 89c545852..35d3ff866 100644
--- a/src/PhpSpreadsheet/Worksheet/Worksheet.php
+++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php
@@ -662,6 +662,16 @@ class Worksheet implements IComparable
return false;
}
+ public function getChartByNameOrThrow(string $chartName): Chart
+ {
+ $chart = $this->getChartByName($chartName);
+ if ($chart !== false) {
+ return $chart;
+ }
+
+ throw new Exception("Sheet does not have a chart named $chartName.");
+ }
+
/**
* Refresh column dimensions.
*
diff --git a/tests/PhpSpreadsheetTests/Chart/ChartsByNameTest.php b/tests/PhpSpreadsheetTests/Chart/ChartsByNameTest.php
new file mode 100644
index 000000000..a3583672f
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Chart/ChartsByNameTest.php
@@ -0,0 +1,97 @@
+getActiveSheet();
+ $sheet->setTitle('Only Sheet');
+ $sheet->fromArray(
+ [
+ ['Some Title'],
+ [],
+ [null, null, 'Data'],
+ [null, 'L1', 1.3],
+ [null, 'L2', 1.3],
+ [null, 'L3', 2.3],
+ [null, 'L4', 1.6],
+ [null, 'L5', 1.5],
+ [null, 'L6', 1.4],
+ [null, 'L7', 2.2],
+ [null, 'L8', 1.8],
+ [null, 'L9', 1.1],
+ [null, 'L10', 1.8],
+ [null, 'L11', 1.6],
+ [null, 'L12', 2.7],
+ [null, 'L13', 2.2],
+ [null, 'L14', 1.3],
+ ]
+ );
+
+ $dataSeriesLabels = [
+ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, '\'Only Sheet\'!$B$4', null, 1), // 2010
+ ];
+ // Set the X-Axis Labels
+ $xAxisTickValues = [
+ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, '\'Only Sheet\'!$B$4:$B$17'),
+ ];
+ // Set the Data values for each data series we want to plot
+ $dataSeriesValues = [
+ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, '\'Only Sheet\'!$C$4:$C$17'),
+ ];
+
+ // Build the dataseries
+ $series = new DataSeries(
+ DataSeries::TYPE_BARCHART, // plotType
+ DataSeries::GROUPING_STANDARD, // plotGrouping
+ range(0, count($dataSeriesValues) - 1), // plotOrder
+ $dataSeriesLabels, // plotLabel
+ $xAxisTickValues, // plotCategory
+ $dataSeriesValues, // plotValues
+ );
+
+ // Set the series in the plot area
+ $plotArea = new PlotArea(null, [$series]);
+
+ // Create the chart
+ $chart = new Chart(
+ name: 'namedchart1',
+ plotArea: $plotArea,
+ );
+
+ // Set the position where the chart should appear in the worksheet
+ $chart->setTopLeftPosition('G7');
+ $chart->setBottomRightPosition('N21');
+ // Add the chart to the worksheet
+ $sheet->addChart($chart);
+ $sheet->setSelectedCells('D1');
+ self::assertSame($chart, $sheet->getChartByName('namedchart1'));
+ self::assertSame($chart, $sheet->getChartByNameOrThrow('namedchart1'));
+ self::assertFalse($sheet->getChartByName('namedchart2'));
+
+ try {
+ $sheet->getChartByNameOrThrow('namedchart2');
+ $exceptionRaised = false;
+ } catch (SpreadsheetException $e) {
+ self::assertSame('Sheet does not have a chart named namedchart2.', $e->getMessage());
+ $exceptionRaised = true;
+ }
+
+ self::assertTrue($exceptionRaised);
+
+ $spreadsheet->disconnectWorksheets();
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Chart/PlotAreaTest.php b/tests/PhpSpreadsheetTests/Chart/PlotAreaTest.php
new file mode 100644
index 000000000..819e41cec
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Chart/PlotAreaTest.php
@@ -0,0 +1,48 @@
+getPlotAreaOrThrow());
+ }
+
+ public function testNoPlotArea(): void
+ {
+ $chart = new Chart('chart1');
+ $this->expectException(ChartException::class);
+ $this->expectExceptionMessage('Chart has no PlotArea');
+ $chart->getPlotAreaOrThrow();
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/RichTextTest.php b/tests/PhpSpreadsheetTests/RichTextTest.php
index 3ebd099c0..513dcf7a9 100644
--- a/tests/PhpSpreadsheetTests/RichTextTest.php
+++ b/tests/PhpSpreadsheetTests/RichTextTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests;
+use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\RichText\TextElement;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
@@ -48,4 +49,20 @@ class RichTextTest extends TestCase
self::assertSame([['ABC', '-3.5']], $sheet->toArray());
$spreadsheet->disconnectWorksheets();
}
+
+ public function testNullFont(): void
+ {
+ $richText = new RichText();
+ $textRun = $richText->createTextRun('hello');
+ self::assertNotNull($textRun->getFontOrThrow());
+ $textRun->setFont(null);
+
+ try {
+ $textRun->getFontOrThrow();
+ $foundFont = true;
+ } catch (SpreadsheetException $e) {
+ $foundFont = false;
+ }
+ self::assertFalse($foundFont, 'expected exception not received');
+ }
}