/** * Returns the rules array used by CModel. * * @param \CModel $model * * @return array */ public static function getRules(\CModel $model) { $rules = array(); $uniqueAttributes = array(); $uniqueRequiredAttributes = array(); $requiredAttributes = array(); $emailAttributes = array(); $urlAttributes = array(); $urlFormatAttributes = array(); $uriAttributes = array(); $strictLengthAttributes = array(); $minLengthAttributes = array(); $maxLengthAttributes = array(); $attributes = $model->getAttributeConfigs(); foreach ($attributes as $name => $config) { switch ($config['type']) { case AttributeType::DateTime: $rules[] = array($name, 'Craft\\DateTimeValidator'); break; case AttributeType::Email: $emailAttributes[] = $name; break; case AttributeType::Enum: $rules[] = array($name, 'in', 'range' => ArrayHelper::stringToArray($config['values'])); break; case AttributeType::Handle: $rules[] = array($name, 'Craft\\HandleValidator', 'reservedWords' => ArrayHelper::stringToArray($config['reservedWords'])); break; case AttributeType::Locale: $rules[] = array($name, 'Craft\\LocaleValidator'); break; case AttributeType::Number: $rule = array($name, 'numerical'); if ($config['min'] !== null) { $rule['min'] = $config['min']; } if ($config['max'] !== null) { $rule['max'] = $config['max']; } if (!$config['decimals']) { $rule['integerOnly'] = true; } $rules[] = $rule; break; case AttributeType::Url: $urlAttributes[] = $name; break; case AttributeType::UrlFormat: $urlFormatAttributes[] = $name; break; case AttributeType::Uri: $uriAttributes[] = $name; break; } // Uniques if (!empty($config['unique'])) { if (empty($config['required']) && (isset($config['null']) && $config['null'] === false)) { $uniqueRequiredAttributes[] = $name; } else { $uniqueAttributes[] = $name; } } // Required if ($config['type'] != AttributeType::Bool && !empty($config['required'])) { $requiredAttributes[] = $name; } // Lengths if ($config['type'] != AttributeType::Number && $config['type'] != AttributeType::Mixed) { if (isset($config['length']) && is_numeric($config['length'])) { $strictLengthAttributes[(string) $config['length']][] = $name; } else { // Only worry about min- and max-lengths if a strict length isn't set if (isset($config['minLength']) && is_numeric($config['minLength'])) { $minLengthAttributes[(string) $config['minLength']][] = $name; } if (isset($config['maxLength']) && is_numeric($config['maxLength'])) { $maxLengthAttributes[(string) $config['maxLength']][] = $name; } } } // Compare with other attributes if (isset($config['compare'])) { $comparisons = ArrayHelper::stringToArray($config['compare']); foreach ($comparisons as $comparison) { if (preg_match('/^(==|=|!=|>=|>|<=|<)\\s*\\b(.*)$/', $comparison, $match)) { $rules[] = array($name, 'compare', 'compareAttribute' => $match[2], 'operator' => $match[1], 'allowEmpty' => true); } } } // Regex pattern matching if (!empty($config['matchPattern'])) { $rules[] = array($name, 'match', 'pattern' => $config['matchPattern']); } } // If this is a BaseRecord instance, catch any unique/required indexes. We don't validate required BELONGS_TO // relations because they might not get set until after validation. if ($model instanceof BaseRecord) { foreach ($model->defineIndexes() as $config) { $unique = !empty($config['unique']); $required = !empty($config['required']); if ($unique || $required) { $columns = ArrayHelper::stringToArray($config['columns']); if ($unique) { if (count($columns) == 1) { if (empty($attributes[$columns[0]]['required']) && (isset($attributes[$columns[0]]['null']) && $attributes[$columns[0]]['null'] === false)) { $uniqueRequiredAttributes[] = $columns[0]; } else { $uniqueAttributes[] = $columns[0]; } } else { $initialColumn = array_shift($columns); $rules[] = array($initialColumn, 'Craft\\CompositeUniqueValidator', 'with' => implode(',', $columns)); } } if ($required) { $requiredAttributes = array_merge($requiredAttributes, $columns); } } } } if ($uniqueAttributes) { $rules[] = array(implode(',', $uniqueAttributes), 'unique'); } if ($uniqueRequiredAttributes) { $rules[] = array(implode(',', $uniqueRequiredAttributes), 'unique', 'allowEmpty' => false); } if ($requiredAttributes) { $rules[] = array(implode(',', $requiredAttributes), 'required'); } if ($emailAttributes) { $rules[] = array(implode(',', $emailAttributes), 'email'); } if ($urlAttributes) { $rules[] = array(implode(',', $urlAttributes), 'Craft\\UrlValidator', 'defaultScheme' => 'http'); } if ($urlFormatAttributes) { $rules[] = array(implode(',', $urlFormatAttributes), 'Craft\\UrlFormatValidator'); } if ($uriAttributes) { $rules[] = array(implode(',', $uriAttributes), 'Craft\\UriValidator'); } if ($strictLengthAttributes) { foreach ($strictLengthAttributes as $strictLength => $attributeNames) { $rules[] = array(implode(',', $attributeNames), 'length', 'is' => (int) $strictLength); } } if ($minLengthAttributes) { foreach ($minLengthAttributes as $minLength => $attributeNames) { $rules[] = array(implode(',', $attributeNames), 'length', 'min' => (int) $minLength); } } if ($maxLengthAttributes) { foreach ($maxLengthAttributes as $maxLength => $attributeNames) { $rules[] = array(implode(',', $attributeNames), 'length', 'max' => (int) $maxLength); } } $rules[] = array(implode(',', array_keys($attributes)), 'safe', 'on' => 'search'); return $rules; }