mirror of
https://github.com/Karaka-Management/Resources.git
synced 2026-01-18 07:58:41 +00:00
165 lines
6.1 KiB
PHP
165 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
|
use PhpOffice\PhpSpreadsheet\Exception;
|
|
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
|
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
|
|
|
|
/**
|
|
* @method TextValue contains(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL)
|
|
* @method TextValue doesNotContain(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL)
|
|
* @method TextValue doesntContain(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL)
|
|
* @method TextValue beginsWith(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL)
|
|
* @method TextValue startsWith(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL)
|
|
* @method TextValue endsWith(string $value, string $operandValueType = Wizard::VALUE_TYPE_LITERAL)
|
|
*/
|
|
class TextValue extends WizardAbstract implements WizardInterface
|
|
{
|
|
protected const MAGIC_OPERATIONS = [
|
|
'contains' => Conditional::OPERATOR_CONTAINSTEXT,
|
|
'doesntContain' => Conditional::OPERATOR_NOTCONTAINS,
|
|
'doesNotContain' => Conditional::OPERATOR_NOTCONTAINS,
|
|
'beginsWith' => Conditional::OPERATOR_BEGINSWITH,
|
|
'startsWith' => Conditional::OPERATOR_BEGINSWITH,
|
|
'endsWith' => Conditional::OPERATOR_ENDSWITH,
|
|
];
|
|
|
|
protected const OPERATORS = [
|
|
Conditional::OPERATOR_CONTAINSTEXT => Conditional::CONDITION_CONTAINSTEXT,
|
|
Conditional::OPERATOR_NOTCONTAINS => Conditional::CONDITION_NOTCONTAINSTEXT,
|
|
Conditional::OPERATOR_BEGINSWITH => Conditional::CONDITION_BEGINSWITH,
|
|
Conditional::OPERATOR_ENDSWITH => Conditional::CONDITION_ENDSWITH,
|
|
];
|
|
|
|
protected const EXPRESSIONS = [
|
|
Conditional::OPERATOR_CONTAINSTEXT => 'NOT(ISERROR(SEARCH(%s,%s)))',
|
|
Conditional::OPERATOR_NOTCONTAINS => 'ISERROR(SEARCH(%s,%s))',
|
|
Conditional::OPERATOR_BEGINSWITH => 'LEFT(%s,LEN(%s))=%s',
|
|
Conditional::OPERATOR_ENDSWITH => 'RIGHT(%s,LEN(%s))=%s',
|
|
];
|
|
|
|
/** @var string */
|
|
protected $operator;
|
|
|
|
/** @var string */
|
|
protected $operand;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $operandValueType;
|
|
|
|
public function __construct(string $cellRange)
|
|
{
|
|
parent::__construct($cellRange);
|
|
}
|
|
|
|
protected function operator(string $operator): void
|
|
{
|
|
if (!isset(self::OPERATORS[$operator])) {
|
|
throw new Exception('Invalid Operator for Text Value CF Rule Wizard');
|
|
}
|
|
|
|
$this->operator = $operator;
|
|
}
|
|
|
|
protected function operand(string $operand, string $operandValueType = Wizard::VALUE_TYPE_LITERAL): void
|
|
{
|
|
$operand = $this->validateOperand($operand, $operandValueType);
|
|
|
|
$this->operand = $operand;
|
|
$this->operandValueType = $operandValueType;
|
|
}
|
|
|
|
protected function wrapValue(string $value): string
|
|
{
|
|
return '"' . $value . '"';
|
|
}
|
|
|
|
protected function setExpression(): void
|
|
{
|
|
$operand = $this->operandValueType === Wizard::VALUE_TYPE_LITERAL
|
|
? $this->wrapValue(\str_replace('"', '""', $this->operand))
|
|
: $this->cellConditionCheck($this->operand);
|
|
|
|
if (
|
|
$this->operator === Conditional::OPERATOR_CONTAINSTEXT ||
|
|
$this->operator === Conditional::OPERATOR_NOTCONTAINS
|
|
) {
|
|
$this->expression = \sprintf(self::EXPRESSIONS[$this->operator], $operand, $this->referenceCell);
|
|
} else {
|
|
$this->expression = \sprintf(self::EXPRESSIONS[$this->operator], $this->referenceCell, $operand, $operand);
|
|
}
|
|
}
|
|
|
|
public function getConditional(): Conditional
|
|
{
|
|
$this->setExpression();
|
|
|
|
$conditional = new Conditional();
|
|
$conditional->setConditionType(self::OPERATORS[$this->operator]);
|
|
$conditional->setOperatorType($this->operator);
|
|
$conditional->setText(
|
|
$this->operandValueType !== Wizard::VALUE_TYPE_LITERAL
|
|
? $this->cellConditionCheck($this->operand)
|
|
: $this->operand
|
|
);
|
|
$conditional->setConditions([$this->expression]);
|
|
$conditional->setStyle($this->getStyle());
|
|
$conditional->setStopIfTrue($this->getStopIfTrue());
|
|
|
|
return $conditional;
|
|
}
|
|
|
|
public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface
|
|
{
|
|
if (!\in_array($conditional->getConditionType(), self::OPERATORS, true)) {
|
|
throw new Exception('Conditional is not a Text Value CF Rule conditional');
|
|
}
|
|
|
|
$wizard = new self($cellRange);
|
|
$wizard->operator = (string) \array_search($conditional->getConditionType(), self::OPERATORS, true);
|
|
$wizard->style = $conditional->getStyle();
|
|
$wizard->stopIfTrue = $conditional->getStopIfTrue();
|
|
|
|
// Best-guess to try and identify if the text is a string literal, a cell reference or a formula?
|
|
$wizard->operandValueType = Wizard::VALUE_TYPE_LITERAL;
|
|
$condition = $conditional->getText();
|
|
if (\preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '$/i', $condition)) {
|
|
$wizard->operandValueType = Wizard::VALUE_TYPE_CELL;
|
|
$condition = self::reverseAdjustCellRef($condition, $cellRange);
|
|
} elseif (
|
|
\preg_match('/\(\)/', $condition) ||
|
|
\preg_match('/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', $condition)
|
|
) {
|
|
$wizard->operandValueType = Wizard::VALUE_TYPE_FORMULA;
|
|
}
|
|
$wizard->operand = $condition;
|
|
|
|
return $wizard;
|
|
}
|
|
|
|
/**
|
|
* @param string $methodName
|
|
* @param mixed[] $arguments
|
|
*/
|
|
public function __call($methodName, $arguments): self
|
|
{
|
|
if (!isset(self::MAGIC_OPERATIONS[$methodName])) {
|
|
throw new Exception('Invalid Operation for Text Value CF Rule Wizard');
|
|
}
|
|
|
|
$this->operator(self::MAGIC_OPERATIONS[$methodName]);
|
|
//$this->operand(...$arguments);
|
|
if (\count($arguments) < 2) {
|
|
$this->operand($arguments[0]);
|
|
} else {
|
|
$this->operand($arguments[0], $arguments[1]);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
}
|