{"record":{"id":"dafbbf32b60b9406","repo":"PHPOffice/PhpSpreadsheet","slug":"conditional-is-not-a-text-value-cf-rule-conditiona","errorCode":null,"errorMessage":"Conditional is not a Text Value CF Rule conditional","messagePattern":"Conditional is not a Text Value CF Rule conditional","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/TextValue.php","lineNumber":115,"sourceCode":"        $conditional = new Conditional();\n        $conditional->setConditionType(self::OPERATORS[$this->operator]);\n        $conditional->setOperatorType($this->operator);\n        $conditional->setText(\n            $this->operandValueType !== Wizard::VALUE_TYPE_LITERAL\n                ? $this->cellConditionCheck($this->operand)\n                : $this->operand\n        );\n        $conditional->setConditions([$this->expression]);\n        $conditional->setStyle($this->getStyle());\n        $conditional->setStopIfTrue($this->getStopIfTrue());\n\n        return $conditional;\n    }\n\n    public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface\n    {\n        if (!in_array($conditional->getConditionType(), self::OPERATORS, true)) {\n            throw new Exception('Conditional is not a Text Value CF Rule conditional');\n        }\n\n        $wizard = new self($cellRange);\n        $wizard->operator = (string) array_search($conditional->getConditionType(), self::OPERATORS, true);\n        $wizard->style = $conditional->getStyle();\n        $wizard->stopIfTrue = $conditional->getStopIfTrue();\n\n        // Best-guess to try and identify if the text is a string literal, a cell reference or a formula?\n        $wizard->operandValueType = Wizard::VALUE_TYPE_LITERAL;\n        $condition = $conditional->getText();\n        if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '$/i', $condition)) {\n            $wizard->operandValueType = Wizard::VALUE_TYPE_CELL;\n            $condition = self::reverseAdjustCellRef($condition, $cellRange);\n        } elseif (\n            preg_match('/\\(\\)/', $condition)\n            || preg_match('/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', $condition)\n        ) {\n            $wizard->operandValueType = Wizard::VALUE_TYPE_FORMULA;","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/TextValue.php#L97-L133","documentation":"Wizard\\TextValue::fromConditional() rebuilds a TextValue wizard from an existing Conditional, but only for the four text condition types in its OPERATORS map: containsText, notContainsText, beginsWith and endsWith. Other condition types - including blanks and expression rules that test text - are rejected up front.","triggerScenarios":"Calling TextValue::fromConditional() on a Conditional whose type is containsBlanks, expression, cellIs or timePeriod; passing a SEARCH()-based expression rule that behaves like 'contains' but was saved as CONDITION_EXPRESSION.","commonSituations":"Text filters implemented as expression formulas in imported files; generic rule editors assuming any text-related rule is a TextValue rule; mixed-rule conversion loops.","solutions":["Check getConditionType() is one of containsText, notContainsText, beginsWith, endsWith before calling","Use Wizard::fromConditional() for automatic dispatch","If the rule is an expression-based text test, convert it with Wizard\\Expression::fromConditional() instead","Guard batch loops with try/catch"],"exampleFix":"// before\n$wizard = Wizard\\TextValue::fromConditional($conditional); // throws unless text type\n\n// after\nuse PhpOffice\\PhpSpreadsheet\\Style\\Conditional;\n\nif (in_array($conditional->getConditionType(), [\n    Conditional::CONDITION_CONTAINSTEXT, Conditional::CONDITION_NOTCONTAINSTEXT,\n    Conditional::CONDITION_BEGINSWITH, Conditional::CONDITION_ENDSWITH,\n], true)) {\n    $wizard = Wizard\\TextValue::fromConditional($conditional);\n} else {\n    $wizard = Wizard::fromConditional($conditional);\n}","handlingStrategy":"type-guard","validationCode":"use PhpOffice\\PhpSpreadsheet\\Style\\Conditional;\n\nif (in_array($conditional->getConditionType(), [\n    Conditional::CONDITION_CONTAINSTEXT, Conditional::CONDITION_NOTCONTAINSTEXT,\n    Conditional::CONDITION_BEGINSWITH, Conditional::CONDITION_ENDSWITH,\n], true)) {\n    $wizard = Wizard\\TextValue::fromConditional($conditional, $cellRange);\n} else {\n    $wizard = Wizard::fromConditional($conditional, $cellRange);\n}","typeGuard":"function isTextValueConditional(Conditional $conditional): bool\n{\n    return in_array($conditional->getConditionType(), [\n        Conditional::CONDITION_CONTAINSTEXT,\n        Conditional::CONDITION_NOTCONTAINSTEXT,\n        Conditional::CONDITION_BEGINSWITH,\n        Conditional::CONDITION_ENDSWITH,\n    ], true);\n}","tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Exception as PhpSpreadsheetException;\n\ntry {\n    $wizard = Wizard\\TextValue::fromConditional($conditional, $cellRange);\n} catch (PhpSpreadsheetException $e) {\n    $wizard = Wizard::fromConditional($conditional, $cellRange);\n}","preventionTips":["Check the condition type is one of the four text types before calling the TextValue factory","SEARCH()-based text checks stored as formulas are EXPRESSION rules","Use the generic Wizard::fromConditional() for mixed or imported rule sets","Remember the text operand lives in getText(), not in getConditions()"],"tags":["php","phpspreadsheet","conditional-formatting","wizard","text-value","type-mismatch"],"backgroundTag":"conditional-rule-type-mismatch","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}