This document explains the custom validation rules in Lychee, their purposes, and implementation patterns. Lychee uses Laravel's validation system with extensive custom rules to ensure data integrity and security.
Lychee implements comprehensive validation through custom Laravel validation rules. These rules handle domain-specific validation requirements that go beyond Laravel's built-in validation rules, ensuring data consistency, security, and proper business logic enforcement.
Purpose: Validate various identifier formats used throughout Lychee
RandomIDRule.php- Validates Lychee's random ID format (base64-like strings)RandomIDListRule.php- Validates arrays of random IDsAlbumIDRule.php- Validates album IDs (random IDs + smart album types)AlbumIDListRule.php- Validates arrays of album IDsIntegerIDRule.php- Validates integer-based IDsOwnerIdRule.php- Validates user/owner ID references
Purpose: Validate configuration values and keys with type safety
ConfigKeyRule.php- Validates configuration key namesConfigValueRule.php- Validates configuration values with type checkingOwnerConfigRule.php- Validates owner-specific configuration settings
Purpose: Validate user-provided content with security considerations
TitleRule.php- Validates album/photo titlesDescriptionRule.php- Validates descriptions with length and content rulesCopyrightRule.php- Validates copyright information formatUsernameRule.php- Validates username format and restrictionsPasswordRule.php- Validates password strength and requirementsCurrentPasswordRule.php- Validates current password for sensitive operations
Purpose: Validate file-related operations and formats
ExtensionRule.php- Validates file extensions against allowed typesFileUuidRule.php- Validates file UUID format for uploadsPhotoUrlRule.php- Validates photo URL format and accessibility
Purpose: Handle conditional validation based on system support
StringRule.php- Basic string validation with custom constraintsStringRequireSupportRule.php- String validation requiring license verificationBooleanRequireSupportRule.php- Boolean validation with support requirementsIntegerRequireSupportRule.php- Integer validation with support requirementsEnumRequireSupportRule.php- Enum validation with support requirementsConfigKeyRequireSupportRule.php- Configuration key validation with support requirements
📝 Note: Some rules use ValidateTrait.php as a legacy mechanism for compatibility with Laravel's validation system evolution from version 9 to 10.
// ValidateTrait.php - Legacy compatibility
trait ValidateTrait
{
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if (!$this->passes($attribute, $value)) {
$fail($this->message());
}
}
}Rules using ValidateTrait:
AlbumIDRuleRandomIDRuleConfigValueRule- Most ID and basic validation rules
Pattern Usage:
final class RandomIDRule implements ValidationRule
{
use ValidateTrait; // Legacy compatibility
public function passes(string $attribute, mixed $value): bool
{
// Validation logic
}
public function message(): string
{
// Error message
}
}Newer rules implement ValidationRule directly:
final class StringRequireSupportRule implements ValidationRule
{
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
// Direct validation implementation
if (!$this->isValid($value)) {
$fail('Validation failed');
}
}
}The ConfigValueRule demonstrates advanced validation patterns including data awareness and complex validation logic:
final class ConfigValueRule implements DataAwareRule, ValidationRule
{
use ValidateTrait;
/** @var Collection<int,Configs> */
private Collection $configs;
/**
* All of the data under validation.
*
* @var array<string,mixed>
*/
protected $data = [];
public function __construct()
{
$this->configs = Configs::all();
}
/**
* Set the data under validation.
*
* @param array<string,mixed> $data
*/
public function setData(array $data): static
{
$this->data = $data;
return $this;
}
public function passes(string $attribute, mixed $value): bool
{
// Parse nested attribute path (e.g., "settings.0.value")
$path = explode('.', $attribute);
if (count($path) !== 3) {
throw new LycheeLogicException('ConfigValueRule: attribute must be in the form of "xxx.*.value"');
}
// Extract configuration key from related data
$array_key = $this->data[$path[0]][intval($path[1])]['key'];
// Validate value against configuration schema
$template = 'Error: Expected %s, got ' . ($value ?? 'NULL') . '.';
return '' === $this->configs->first(fn (Configs $c) => $c->key === $array_key)->sanity($value, $template);
}
public function message(): string
{
return ':attribute is not a valid configuration value.';
}
}1. Data Awareness (DataAwareRule)
- Implements
setData()to access all form data - Enables cross-field validation logic
- Allows validation based on related field values
2. Complex Attribute Parsing
- Handles nested array attributes (
settings.0.value) - Extracts related configuration keys from sibling fields
- Provides meaningful error context
3. Dynamic Validation Logic
- Loads all configuration schemas at runtime
- Validates values against specific configuration type requirements
- Uses configuration's built-in
sanity()method for type checking
4. Usage in Nested Forms
// Example form data structure:
[
'settings' => [
0 => ['key' => 'gallery_title', 'value' => 'My Gallery'],
1 => ['key' => 'upload_chunk_size', 'value' => '1024'],
]
]
// ConfigValueRule validates that 'value' matches the expected type for 'key'Validation rules are used in Request classes:
class UpdateAlbumRequest extends BaseApiRequest
{
public function rules(): array
{
return [
'id' => ['required', new AlbumIDRule(false)],
'title' => ['sometimes', new TitleRule()],
'description' => ['sometimes', new DescriptionRule()],
'parent_id' => ['sometimes', new AlbumIDRule(true)],
];
}
}This validation rule system ensures that Lychee maintains high data quality and security standards while providing clear, maintainable validation logic throughout the application.
Last updated: August 14, 2025