# tablepress/3.4/libraries/vendor/PhpSpreadsheet/Calculation/LookupRef/Indirect.php

TablePress – Tables in WordPress made easy, version 3.4. 131 lines.

- Page: https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/LookupRef/Indirect.php
- Raw: https://pluginprobe.com/plugins/tablepress/3.4/raw/libraries/vendor/PhpSpreadsheet/Calculation/LookupRef/Indirect.php
- Modified: 2026-04-07T08:40:50+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/LookupRef/Indirect.php#L10-L20`.

```php
<?php

namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\LookupRef;

use Exception;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use TablePress\PhpOffice\PhpSpreadsheet\Cell\AddressRange;
use TablePress\PhpOffice\PhpSpreadsheet\Cell\Cell;
use TablePress\PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class Indirect
{
	/**
	 * Determine whether cell address is in A1 (true) or R1C1 (false) format.
	 *
	 * @param mixed $a1fmt Expect bool Helpers::CELLADDRESS_USE_A1 or CELLADDRESS_USE_R1C1,
	 *                      but can be provided as numeric which is cast to bool
	 */
	private static function a1Format($a1fmt): bool
	{
		$a1fmt = Functions::flattenSingleValue($a1fmt);
		if ($a1fmt === null) {
			return Helpers::CELLADDRESS_USE_A1;
		}
		if (is_string($a1fmt)) {
			throw new Exception(ExcelError::VALUE());
		}

		return (bool) $a1fmt;
	}

	/**
	 * Convert cellAddress to string, verify not null string.
	 *
	 * @param null|mixed[]|string $cellAddress
	 */
	private static function validateAddress($cellAddress): string
	{
		$cellAddress = Functions::flattenSingleValue($cellAddress);
		if (!is_string($cellAddress) || !$cellAddress) {
			throw new Exception(ExcelError::REF());
		}

		return $cellAddress;
	}

	/**
	 * INDIRECT.
	 *
	 * Returns the reference specified by a text string.
	 * References are immediately evaluated to display their contents.
	 *
	 * Excel Function:
	 *        =INDIRECT(cellAddress, bool) where the bool argument is optional
	 *
	 * @param mixed[]|string $cellAddress $cellAddress The cell address of the current cell (containing this formula)
	 * @param mixed $a1fmt Expect bool Helpers::CELLADDRESS_USE_A1 or CELLADDRESS_USE_R1C1,
	 *                      but can be provided as numeric which is cast to bool
	 * @param Cell $cell The current cell (containing this formula)
	 *
	 * @return mixed[]|string An array containing a cell or range of cells, or a string on error
	 */
	public static function INDIRECT($cellAddress, $a1fmt, Cell $cell)
	{
		[$baseCol, $baseRow] = Coordinate::indexesFromString($cell->getCoordinate());

		try {
			$a1 = self::a1Format($a1fmt);
			$cellAddress = self::validateAddress($cellAddress);
		} catch (Exception $e) {
			return $e->getMessage();
		}

		[$cellAddress, $worksheet, $sheetName] = Helpers::extractWorksheet($cellAddress, $cell);

		if (preg_match('/^' . Calculation::CALCULATION_REGEXP_COLUMNRANGE_RELATIVE . '$/miu', $cellAddress, $matches)) {
			$cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress));
		} elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_ROWRANGE_RELATIVE . '$/miu', $cellAddress, $matches)) {
			$cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress));
		}

		try {
			[$cellAddress1, $cellAddress2, $cellAddress] = Helpers::extractCellAddresses($cellAddress, $a1, $cell->getWorkSheet(), $sheetName, $baseRow, $baseCol);
		} catch (Exception $exception) {
			return ExcelError::REF();
		}

		if (
			(!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress1, $matches))
			|| (($cellAddress2 !== null) && (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress2, $matches)))
		) {
			return ExcelError::REF();
		}

		return self::extractRequiredCells($worksheet, $cellAddress);
	}

	/**
	 * Extract range values.
	 *
	 * @return mixed[] Array of values in range if range contains more than one element.
	 *                  Otherwise, a single value is returned.
	 */
	private static function extractRequiredCells(?Worksheet $worksheet, string $cellAddress): array
	{
		return Calculation::getInstance(($nullsafeVariable1 = $worksheet) ? $nullsafeVariable1->getParent() : null)
			->extractCellRange($cellAddress, $worksheet, false, true);
	}

	private static function handleRowColumnRanges(?Worksheet $worksheet, string $start, string $end): string
	{
		// Being lazy, we're only checking a single row/column to get the max
		if (ctype_digit($start) && $start <= AddressRange::MAX_ROW) {
			// Max 16,384 columns for Excel2007
			$endColRef = ($worksheet !== null) ? $worksheet->getHighestDataColumn((int) $start) : AddressRange::MAX_COLUMN;

			return "A{$start}:{$endColRef}{$end}";
		} elseif (ctype_alpha($start) && strlen($start) <= 3) {
			// Max 1,048,576 rows for Excel2007
			$endRowRef = ($worksheet !== null) ? $worksheet->getHighestDataRow($start) : AddressRange::MAX_ROW;

			return "{$start}1:{$end}{$endRowRef}";
		}

		return "{$start}:{$end}";
	}
}

```
