VOOZH about

URL: https://deepwiki.com/mathsgod/light/7.1-filesystem-architecture

⇱ Filesystem Architecture | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

Filesystem Architecture

Purpose and Scope

This document describes the filesystem abstraction layer in the Light framework, which provides unified access to multiple storage backends through Flysystem's MountManager. The architecture enables applications to work with local and cloud storage (S3, Aliyun OSS, Hostlink, FTP) through a common interface.

For file operation mutations (create, delete, rename, upload), see FileSystemController. For GraphQL-exposed file properties and queries, see Node Types. For configuration management of filesystem backends, see Filesystem Configuration Management.


Architecture Overview

The filesystem architecture consists of three main layers: configuration management, abstraction layer, and storage backends.

Filesystem Architecture Layers


Sources: src/App.php134-147 src/Type/Filesystem.php1-198 src/Filesystem/Node/Node.php1-25


MountManager Initialization

The MountManager is initialized in the App class constructor and provides a unified interface for multiple filesystem backends. Each configured filesystem is registered with a unique name that serves as a protocol prefix in file paths.

MountManager Initialization Flow


Sources: src/App.php134-147 src/App.php695-715 src/App.php717-787

The initialization process:

  1. Configuration Retrieval: getFSConfig() reads the fs key from the Config model src/App.php695-715
  2. Default Fallback: If no configuration exists, a default local filesystem is added with location getcwd()/uploads src/App.php704-713
  3. Filesystem Creation: For each configuration, getFS(index) creates the appropriate adapter src/App.php717-787
  4. MountManager Assembly: All filesystems are registered in a MountManager instance with their configured names src/App.php134-147
  5. Container Registration: The MountManager is added to the DI container for autowiring src/App.php146

Configuration Structure

Each filesystem configuration in the JSON array contains:

FieldTypeDescription
namestringUnique identifier used as protocol prefix (e.g., "local", "s3-bucket")
typestringBackend type: "local", "s3", "aliyun-oss", "hostlink", "ftp"
dataobjectBackend-specific configuration parameters

Sources: src/App.php695-715


Filesystem Configuration Storage

Filesystem configurations are stored as JSON in the Config model under the key fs. The getFSConfig() method retrieves and parses this configuration, ensuring at least one filesystem (local) is always available.

Default Local Filesystem

When no configuration exists, the system automatically provides:


Sources: src/App.php704-713

Configuration Access Pattern


Sources: src/App.php695-715

The MountManager is accessible via:

  • App::getMountManager() method src/App.php149-152
  • Dependency injection via #[Autowire] MountManager $mountManager in GraphQL resolvers

Storage Backend Implementations

The App::getFS(int $index) method creates Filesystem instances based on the configuration type. Each backend has specific adapter initialization logic.

Supported Backends and Adapters


Sources: src/App.php717-787

Local Filesystem

Configuration Parameters:

  • location: Root directory path (required)
  • public_url: Public URL base path (optional)

Implementation: Uses LocalFilesystemAdapter with custom PortableVisibilityConverter to set file permissions (0640) and directory permissions (0777) src/App.php723-742

Amazon S3

Configuration Parameters:

  • region: AWS region (required)
  • endpoint: AWS endpoint URL (required)
  • bucket: S3 bucket name (required)
  • accessKey: AWS access key (required)
  • secretKey: AWS secret key (required)
  • prefix: Path prefix inside bucket (optional)
  • visibility: Default visibility setting (optional)

Implementation: Creates Aws\S3\S3Client with credentials, then wraps in AwsS3V3Adapter with visibility converter src/App.php749-778

Aliyun OSS

Configuration Parameters:

  • access_key_id: Access key ID (required)
  • access_key_secret: Access key secret (required)
  • endpoint: OSS endpoint (required)
  • bucket: OSS bucket name (required)

Implementation: Uses AliyunFactory::createFilesystem() to create a pre-configured filesystem src/App.php745-747

Hostlink Storage

Configuration Parameters:

  • token: Hostlink access token (required)
  • endpoint: Hostlink API endpoint (required)

Implementation: Uses custom HL\Storage\Adapter provided by the hostlink/hostlink-storage-adapter package src/App.php780-784

Package Detection

The Type\Filesystem::getTypes() method dynamically determines which backends are available by checking installed Composer packages:


This prevents users from configuring backends when the required adapter package is not installed src/Type/Filesystem.php51-96

Sources: src/App.php717-787 src/Type/Filesystem.php31-108


Node Abstraction Layer

The Node system provides a GraphQL-friendly abstraction over filesystem entries. The Node interface defines common operations, implemented by File and Folder classes.

Node Type Hierarchy


Sources: src/Filesystem/Node/Node.php1-25 src/Filesystem/Node/File.php1-98 src/Filesystem/Node/Folder.php1-96

Node Interface

All filesystem nodes expose these GraphQL fields:

File Node

The File class represents individual files with lazy-loaded properties:

File Properties:

FieldTypeDescriptionLazy Loaded
namestringFilenameNo
pathstringRelative pathNo
locationstringFull location with protocolNo
sizeintFile size in bytesYes (via MountManager)
contentstringFile contentsYes (via MountManager)
lastModifiedintModification timestampYes (cached in metadata)
mimeTypestringMIME typeYes (via MountManager)
publicUrlstringPublic URL if availableYes (via MountManager)
base64ContentstringBase64-encoded contentYes (via MountManager)

Metadata Caching: The constructor accepts an optional metadata parameter to avoid redundant filesystem calls. When provided, size and lastModified are returned directly from the cache src/Filesystem/Node/File.php50-67

Public URL Fallback: If publicUrl() throws an exception (not supported by adapter), falls back to /api/uploads/{path} src/Filesystem/Node/File.php82-89

Sources: src/Filesystem/Node/File.php1-98

Folder Node

The Folder class represents directories with recursive operations:

Folder Properties:

FieldTypeDescription
namestringFolder name
pathstringRelative path
locationstringFull location with protocol
totalSizeintRecursive size of all contained files
childrenNode[]Direct child files and folders
lastModifiedintModification timestamp

Children Resolution: The getChildren() method lists directory contents non-recursively, instantiating File or Folder objects for each entry. Files/folders starting with '.' are skipped src/Filesystem/Node/Folder.php56-85

Total Size Calculation: Recursively iterates all files using listContents(..., true) and sums their sizes src/Filesystem/Node/Folder.php21-30

Sources: src/Filesystem/Node/Folder.php1-96


GraphQL Query Interface

The Light\Type\Filesystem class provides the GraphQL query interface for filesystem operations. All methods are exposed as GraphQL fields using #[Field] annotations.

Filesystem GraphQL API


Sources: src/Type/Filesystem.php1-198

Query: list()

Returns the filesystem configuration array from App::getFSConfig() src/Type/Filesystem.php22-25

Example Query:


Query: getTypes()

Returns metadata about supported backend types, including configuration options and availability status. Each type includes:

  • label: Human-readable name
  • name: Type identifier
  • disable: Boolean indicating if required package is missing
  • options: Object defining configuration parameters with type, description, and requirements

Backend Detection: Uses \Composer\InstalledVersions::isInstalled() to check for adapter packages src/Type/Filesystem.php51-96

Sources: src/Type/Filesystem.php31-108

Query: node(location)

Returns a Node object (File or Folder) for the given location, or null if not found src/Type/Filesystem.php111-119

Location Format: Must include protocol prefix, e.g., "local://path/to/file.txt"

Implementation:

  1. Check if location is a directory using directoryExists()
  2. If yes, return new Folder(location)
  3. Check if location is a file using fileExists()
  4. If yes, return new File(location)
  5. Otherwise return null

Sources: src/Type/Filesystem.php111-119

Query: exists(location)

Simple boolean check for file or directory existence src/Type/Filesystem.php122-125

Query: find(search, label)

Recursive search across all configured filesystems with optional filtering:

Parameters:

  • search: Optional keyword to filter by path
  • label: Optional MIME type category ("image", "video", "audio", "document")

Search Algorithm:

  1. Iterate all filesystems from App::getFSConfig()
  2. Use listContents(..., true) for recursive listing
  3. Skip files/folders starting with '.'
  4. Filter by search keyword if provided (case-insensitive substring match)
  5. Filter by label if provided (MIME type prefix matching)
  6. Instantiate File or Folder with cached metadata to avoid re-fetching

Label Matching: The matchesLabel() private method maps labels to MIME type prefixes src/Type/Filesystem.php181-197:

  • image: image/*
  • video: video/*
  • audio: audio/*
  • document: specific MIME types (PDF, Word, Excel, etc.)

Sources: src/Type/Filesystem.php131-197


File Access Routes

The App class registers HTTP routes for direct file access, requiring authentication. Two URL patterns are supported for different use cases.

Route Registration

Routes are registered in the App::run() method using the router from Light\Server src/App.php844-921

Route: /fs/{protocol}/{path}

Serves files using MountManager location strings:

URL Pattern: /api/fs/local/path/to/file.txt

Implementation Flow:


Sources: src/App.php850-865

Security: Requires authentication via Auth\Service::isLogged() src/App.php853

Parameters:

  • protocol: Filesystem name (e.g., "local", "s3")
  • path: URL-encoded file path within the filesystem

The route constructs the location string as {protocol}://{urldecode(path)} and uses MountManager to serve the file with appropriate Content-Type header src/App.php854-861

Route: /drive/{index}/{path}

Legacy route pattern using numeric filesystem index:

URL Pattern: /api/drive/0/path/to/file.txt

Implementation: Delegates to App::getDriveResponse(index, path) which:

  1. Retrieves filesystem config
  2. Validates index bounds
  3. Gets filesystem via getDrive(index)
  4. Checks file existence
  5. Returns response with Content-Type and file contents

Sources: src/App.php867-875 src/App.php540-564

Parameters:

  • index: Zero-based filesystem index from configuration array
  • path: File path within the filesystem

Security and Access Control

The filesystem layer implements multiple security measures to prevent unauthorized access and malicious file operations.

Authentication Requirements

All HTTP file access routes require authentication:

  • Routes create a new Auth\Service instance from the request
  • isLogged() method verifies JWT token or session
  • Unauthenticated requests receive 401 Unauthorized response

Sources: src/App.php852-853 src/App.php869-870

Dot File Protection

Files and folders starting with '.' are systematically excluded from listings and searches to prevent access to hidden system files:

Folder Children Filtering:


src/Filesystem/Node/Folder.php66-69

Search Filtering:


src/Type/Filesystem.php146-148

This prevents exposure of configuration files, version control directories, and other sensitive hidden files.

GraphQL Authorization

GraphQL mutations in FileSystemController use RBAC annotations for permission checking (see FileSystemController for details on #[Right] annotations).


Usage Patterns

Accessing Files via GraphQL

Query a specific file:


List folder contents:


Search for images:


Accessing Files via HTTP

Direct file access (requires authentication):

GET /api/fs/local/uploads/image.jpg
GET /api/fs/s3-bucket/documents/report.pdf

Legacy drive access:

GET /api/drive/0/uploads/image.jpg

Sources: src/App.php850-875


Configuration Example

Complete filesystem configuration stored in Config model (fs key):


This configuration creates a MountManager with three filesystems accessible as:

  • local://path/to/file
  • s3-media://path/to/file
  • oss-backup://path/to/file

Sources: src/App.php695-715