{"record":{"id":"ec7fc5e3b7676e70","repo":"PHPOffice/PhpSpreadsheet","slug":"conditional-is-not-a-blanks-cf-rule-conditional","errorCode":null,"errorMessage":"Conditional is not a Blanks CF Rule conditional","messagePattern":"Conditional is not a Blanks CF Rule conditional","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Blanks.php","lineNumber":71,"sourceCode":"\n        $conditional = new Conditional();\n        $conditional->setConditionType(\n            $this->inverse ? Conditional::CONDITION_CONTAINSBLANKS : Conditional::CONDITION_NOTCONTAINSBLANKS\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 (\n            $conditional->getConditionType() !== Conditional::CONDITION_CONTAINSBLANKS\n            && $conditional->getConditionType() !== Conditional::CONDITION_NOTCONTAINSBLANKS\n        ) {\n            throw new Exception('Conditional is not a Blanks CF Rule conditional');\n        }\n\n        $wizard = new self($cellRange);\n        $wizard->style = $conditional->getStyle();\n        $wizard->stopIfTrue = $conditional->getStopIfTrue();\n        $wizard->inverse = $conditional->getConditionType() === Conditional::CONDITION_CONTAINSBLANKS;\n\n        return $wizard;\n    }\n\n    /**\n     * @param mixed[] $arguments\n     */\n    public function __call(string $methodName, array $arguments): self\n    {\n        if (!array_key_exists($methodName, self::OPERATORS)) {\n            throw new Exception('Invalid Operation for Blanks CF Rule Wizard');\n        }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Blanks.php#L53-L89","documentation":"Wizard\\Blanks::fromConditional() converts an existing Conditional back into a Blanks wizard, but a Blanks wizard can only represent the containsBlanks and notContainsBlanks condition types. Any other condition type is rejected immediately instead of producing a wizard that would silently misrepresent the rule.","triggerScenarios":"Calling Wizard\\Blanks::fromConditional() on a Conditional created by a CellValue, TextValue, Expression or DateValue wizard; looping over mixed conditional rules and forcing each one through the Blanks factory.","commonSituations":"Copy-pasted rule-conversion code that assumes every rule highlights blanks; blank-detection rules that were saved as EXPRESSION rules (LEN(TRIM(A1))=0 formulas) rather than true containsBlanks rules; processing imported files where each rule's type is unknown until runtime.","solutions":["Check that getConditionType() is CONDITION_CONTAINSBLANKS or CONDITION_NOTCONTAINSBLANKS before calling","Use Wizard::fromConditional() for automatic dispatch to the right wizard class","If the rule is an expression-based blank test, convert it with Wizard\\Expression::fromConditional() instead","Wrap batch conversions in try/catch to skip wrong-type rules"],"exampleFix":"// before\n$wizard = Wizard\\Blanks::fromConditional($conditional); // throws unless containsBlanks/notContainsBlanks\n\n// after\nuse PhpOffice\\PhpSpreadsheet\\Style\\Conditional;\n\nif (in_array($conditional->getConditionType(),\n    [Conditional::CONDITION_CONTAINSBLANKS, Conditional::CONDITION_NOTCONTAINSBLANKS], true)) {\n    $wizard = Wizard\\Blanks::fromConditional($conditional);\n} else {\n    $wizard = Wizard::fromConditional($conditional); // correct wizard for the actual type\n}","handlingStrategy":"type-guard","validationCode":"use PhpOffice\\PhpSpreadsheet\\Style\\Conditional;\n\nif (in_array($conditional->getConditionType(),\n    [Conditional::CONDITION_CONTAINSBLANKS, Conditional::CONDITION_NOTCONTAINSBLANKS], true)) {\n    $wizard = Wizard\\Blanks::fromConditional($conditional, $cellRange);\n} else {\n    $wizard = Wizard::fromConditional($conditional, $cellRange);\n}","typeGuard":"function isBlanksConditional(Conditional $conditional): bool\n{\n    return in_array(\n        $conditional->getConditionType(),\n        [Conditional::CONDITION_CONTAINSBLANKS, Conditional::CONDITION_NOTCONTAINSBLANKS],\n        true\n    );\n}","tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Exception as PhpSpreadsheetException;\n\ntry {\n    $wizard = Wizard\\Blanks::fromConditional($conditional, $cellRange);\n} catch (PhpSpreadsheetException $e) {\n    $wizard = Wizard::fromConditional($conditional, $cellRange); // dispatch on real type\n}","preventionTips":["Check getConditionType() against the two blanks constants before calling the Blanks factory","Prefer the generic Wizard::fromConditional() for unknown rule sets","Recognize expression-based blank tests (LEN(TRIM(...))) as EXPRESSION rules, not blanks rules","Keep one shared type-dispatch helper instead of per-class fromConditional calls"],"tags":["php","phpspreadsheet","conditional-formatting","wizard","blanks","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"}