/** * @see CoreExt_Validate_Abstract#_validate() * @throws Exception|FormulaMedia_Validate_Exception */ protected function _validate($value) { // Instancia if (is_null(self::$_model)) { self::$_model = new FormulaMedia_Model_Formula(); } // Adiciona espaços entre os parênteses $value = self::$_model->replaceAliasTokens($value); $tokensAvailable = $this->_getTokens(); $valueTokens = explode(' ', $value); $missingTokens = array(); $numericTokens = array(); // Verifica se alguma token não permitida foi utilizada foreach ($valueTokens as $tk) { if ('' == ($tk = trim($tk))) { continue; } if (!in_array($tk, $tokensAvailable)) { if (!is_numeric($tk)) { $missingTokens[] = $tk; } } elseif (self::$_model->isNumericToken($tk)) { // Se for uma token numérica, atribui um número 1 para usar na fórmula // e avaliar se não lança um erro no PHP $numericTokens[$tk] = 1; } } if (0 < count($missingTokens)) { throw new Exception('As variáveis ou símbolos não são permitidos: ' . implode(', ', $missingTokens)); } // Verifica se a fórmula é parseada corretamente pelo PHP $formula = self::$_model->replaceTokens($value, $numericTokens); /* * Eval, com surpressão de erro para evitar interrupção do script. Se * retornar algum valor diferente de NULL, assume como erro de sintaxe. */ $evaled = @eval('?><?php $result = ' . $formula . '; ?>'); if (!is_null($evaled)) { require_once 'FormulaMedia/Validate/Exception.php'; throw new FormulaMedia_Validate_Exception('A fórmula apresenta erros.' . ' Verifique algum parêntese faltante ou um sinal de operação' . ' matemática sem um operando.'); } return TRUE; }
/** * @expectedException FormulaMedia_Validate_Exception */ public function testFormulaInvalidaPorErroDeSintaxe() { $formula = '(Rc * 0.4) + (Se * 0.6) ()'; $validator = new FormulaMedia_Validate_Formula(array('excludeToken' => NULL)); $this->assertTrue($validator->isValid($formula)); }