/** * Checks to see if a record matches a condition * * @internal * * @param string $operator The record to check * @param mixed $value The value to compare to * @param mixed $result The result of the method call(s) * @return boolean If the comparison was successful */ private static function checkCondition($operator, $value, $result) { $was_array = is_array($value); if (!$was_array) { $value = array($value); } foreach ($value as $i => $_value) { if (is_object($_value)) { if ($_value instanceof fActiveRecord) { continue; } if (method_exists($_value, '__toString')) { $value[$i] = $_value->__toString(); } } } if (!$was_array) { $value = $value[0]; } $was_array = is_array($result); if (!$was_array) { $result = array($result); } foreach ($result as $i => $_result) { if (is_object($_result)) { if ($_result instanceof fActiveRecord) { continue; } if (method_exists($_result, '__toString')) { $result[$i] = $_result->__toString(); } } } if (!$was_array) { $result = $result[0]; } if ($operator == '~' && !is_array($value) && is_array($result)) { $value = fORMDatabase::parseSearchTerms($value, TRUE); } if (in_array($operator, array('~', '&~', '!~', '^~', '$~'))) { settype($value, 'array'); settype($result, 'array'); } switch ($operator) { case '&~': foreach ($value as $_value) { if (fUTF8::ipos($result[0], $_value) === FALSE) { return FALSE; } } break; case '~': // Handles fuzzy search on multiple method calls if (count($result) > 1) { foreach ($value as $_value) { $found = FALSE; foreach ($result as $_result) { if (fUTF8::ipos($_result, $_value) !== FALSE) { $found = TRUE; } } if (!$found) { return FALSE; } } break; } // No break exists since a ~ on a single method call acts // similar to the other LIKE operators // No break exists since a ~ on a single method call acts // similar to the other LIKE operators case '!~': case '^~': case '$~': if ($operator == '$~') { $result_len = fUTF8::len($result[0]); } foreach ($value as $_value) { $pos = fUTF8::ipos($result[0], $_value); if ($operator == '^~' && $pos === 0) { return TRUE; } elseif ($operator == '$~' && $pos === $result_len - fUTF8::len($_value)) { return TRUE; } elseif ($pos !== FALSE) { return $operator != '!~'; } } if ($operator != '!~') { return FALSE; } break; case '=': if ($value instanceof fActiveRecord && $result instanceof fActiveRecord) { if (get_class($value) != get_class($result) || !$value->exists() || !$result->exists() || self::hash($value) != self::hash($result)) { return FALSE; } } elseif (is_array($value) && !in_array($result, $value)) { return FALSE; } elseif (!is_array($value) && $result != $value) { return FALSE; } break; case '!': if ($value instanceof fActiveRecord && $result instanceof fActiveRecord) { if (get_class($value) == get_class($result) && $value->exists() && $result->exists() && self::hash($value) == self::hash($result)) { return FALSE; } } elseif (is_array($value) && in_array($result, $value)) { return FALSE; } elseif (!is_array($value) && $result == $value) { return FALSE; } break; case '<': if ($result >= $value) { return FALSE; } break; case '<=': if ($result > $value) { return FALSE; } break; case '>': if ($result <= $value) { return FALSE; } break; case '>=': if ($result < $value) { return FALSE; } break; } return TRUE; }
/** * Callback for custom SQLite length function; returns the number of UTF-8 characters in a string * * @internal * * @param string $string The string to measure * @return string The current date */ public static function sqliteLength($string) { return fUTF8::len($string); }
/** * Validates a value against the database schema * * @param fSchema $schema The schema object for the object * @param fActiveRecord $object The instance of the class the column is part of * @param string $column The column to check * @param array &$values An associative array of all values going into the row (needs all for multi-field unique constraint checking) * @param array &$old_values The old values from the record * @return string An error message for the column specified */ private static function checkAgainstSchema($schema, $object, $column, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $info = $schema->getColumnInfo($table, $column); // Make sure a value is provided for required columns $schema_not_null = $info['not_null'] && $info['default'] === NULL && $info['auto_increment'] === FALSE; $rule_not_null = isset(self::$required_rules[$class][$column]); if ($values[$column] === NULL && ($schema_not_null || $rule_not_null)) { return self::compose('%sPlease enter a value', fValidationException::formatField(fORM::getColumnName($class, $column))); } $message = self::checkDataType($schema, $class, $column, $values[$column]); if ($message) { return $message; } // Make sure a valid value is chosen if (isset($info['valid_values']) && $values[$column] !== NULL && !in_array($values[$column], $info['valid_values'])) { return self::compose('%1$sPlease choose from one of the following: %2$s', fValidationException::formatField(fORM::getColumnName($class, $column)), join(', ', $info['valid_values'])); } // Make sure the value isn't too long if ($info['type'] == 'varchar' && isset($info['max_length']) && $values[$column] !== NULL && is_string($values[$column]) && fUTF8::len($values[$column]) > $info['max_length']) { return self::compose('%1$sPlease enter a value no longer than %2$s characters', fValidationException::formatField(fORM::getColumnName($class, $column)), $info['max_length']); } // Make sure the value is the proper length if ($info['type'] == 'char' && isset($info['max_length']) && $values[$column] !== NULL && is_string($values[$column]) && fUTF8::len($values[$column]) != $info['max_length']) { return self::compose('%1$sPlease enter exactly %2$s characters', fValidationException::formatField(fORM::getColumnName($class, $column)), $info['max_length']); } // Make sure the value fits in the numeric range if (self::stringlike($values[$column]) && in_array($info['type'], array('integer', 'float')) && $info['min_value'] && $info['max_value'] && ($info['min_value']->gt($values[$column]) || $info['max_value']->lt($values[$column]))) { return self::compose('%1$sPlease enter a number between %2$s and %3$s', fValidationException::formatField(fORM::getColumnName($class, $column)), $info['min_value']->__toString(), $info['max_value']->__toString()); } $message = self::checkForeignKeyConstraints($schema, $class, $column, $values); if ($message) { return $message; } }
/** * Validates a value against the database schema * * @param fActiveRecord $object The instance of the class the column is part of * @param string $column The column to check * @param array &$values An associative array of all values going into the row (needs all for multi-field unique constraint checking) * @param array &$old_values The old values from the record * @return string An error message for the column specified */ private static function checkAgainstSchema($object, $column, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $column_info = fORMSchema::retrieve()->getColumnInfo($table, $column); // Make sure a value is provided for required columns if ($values[$column] === NULL && $column_info['not_null'] && $column_info['default'] === NULL && $column_info['auto_increment'] === FALSE) { return self::compose('%sPlease enter a value', fValidationException::formatField(fORM::getColumnName($class, $column))); } $message = self::checkDataType($class, $column, $values[$column]); if ($message) { return $message; } // Make sure a valid value is chosen if (isset($column_info['valid_values']) && $values[$column] !== NULL && !in_array($values[$column], $column_info['valid_values'])) { return self::compose('%1$sPlease choose from one of the following: %2$s', fValidationException::formatField(fORM::getColumnName($class, $column)), join(', ', $column_info['valid_values'])); } // Make sure the value isn't too long if ($column_info['type'] == 'varchar' && isset($column_info['max_length']) && $values[$column] !== NULL && is_string($values[$column]) && fUTF8::len($values[$column]) > $column_info['max_length']) { return self::compose('%1$sPlease enter a value no longer than %2$s characters', fValidationException::formatField(fORM::getColumnName($class, $column)), $column_info['max_length']); } // Make sure the value is the proper length if ($column_info['type'] == 'char' && isset($column_info['max_length']) && $values[$column] !== NULL && is_string($values[$column]) && fUTF8::len($values[$column]) != $column_info['max_length']) { return self::compose('%1$sPlease enter exactly %2$s characters', fValidationException::formatField(fORM::getColumnName($class, $column)), $column_info['max_length']); } $message = self::checkForeignKeyConstraints($class, $column, $values); if ($message) { return $message; } }