VOOZH about

URL: https://deepwiki.com/mathsgod/light/7-file-storage

⇱ File Storage | mathsgod/light | DeepWiki


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

File Storage

The file storage system provides multi-backend storage abstraction through League Flysystem's MountManager, enabling unified access to local and cloud storage backends. The system exposes a GraphQL API with polymorphic Node types (File and Folder) for type-safe file tree operations.

Key Components:

  • League\Flysystem\MountManager - Multi-filesystem coordinator
  • Light\Filesystem\Node\Node - Polymorphic interface for files and folders
  • Light\Controller\FileSystemController - GraphQL mutation endpoint
  • Light\Type\Filesystem - GraphQL query endpoint

Related Pages:

  • Page 5: Authentication and authorization for file operations
  • Page 4.3.3: FileSystemController GraphQL mutations
  • Page 8.1: Config model for filesystem configuration storage

Sources: src/Filesystem/Node/Node.php1-24 src/Type/Filesystem.php1-198 src/Controller/FileSystemController.php1-364


7.1 Filesystem Architecture

The filesystem architecture consists of three layers: the storage abstraction layer (MountManager), the domain model layer (Node types), and the GraphQL API layer.

MountManager Pattern

The League\Flysystem\MountManager serves as the central abstraction layer, coordinating multiple storage backends (called "filesystems" or "drives"). Each drive is identified by a name prefix in location strings using the format: driveName://path/to/file.

Initialization in App Class:

src/App.php134-146

The MountManager is instantiated in the Light\App constructor and registered in the dependency injection container for autowiring into GraphQL resolvers.

Sources: src/App.php134-146 src/App.php149-152

Configuration Loading

Filesystem configurations are stored in the Config model where name = "fs". The App::getFSConfig() method retrieves these configurations with a default local filesystem fallback:

src/App.php695-714

Each configuration object contains:

  • name: Drive identifier for location strings
  • type: Backend type (local, s3, oss, hostlink, ftp)
  • data: Backend-specific configuration options
  • uuid: Unique identifier for CRUD operations

Sources: src/App.php695-714

Dynamic Adapter Loading

The App::getFS() method instantiates Flysystem adapters based on configuration type, with conditional support based on Composer package availability:


Adapter Factory Implementation:

The method uses a switch statement to instantiate the appropriate adapter based on the type field:

src/App.php717-787

Sources: src/App.php59-147 src/App.php695-787

Location String Format

All file operations use location strings with the drive name as a URI scheme:

<driveName>://<path>

Examples:

  • local://uploads/image.jpg
  • s3://public/documents/report.pdf
  • oss://media/video.mp4

The getPath() method in Node implementations strips the drive prefix:

src/Filesystem/Node/File.php29-39

Sources: src/Filesystem/Node/File.php29-39 src/Filesystem/Node/Folder.php39-43


7.2 Node Types (File and Folder)

The Node interface defines a polymorphic contract for filesystem objects, enabling type-safe GraphQL queries that return either File or Folder instances.

Node Interface

</old_str> <new_str>

File Storage

The file storage system provides multi-backend storage abstraction through League Flysystem's MountManager, enabling unified access to local and cloud storage backends. The system exposes a GraphQL API with polymorphic Node types (File and Folder) for type-safe file tree operations.

Key Components:

  • League\Flysystem\MountManager - Multi-filesystem coordinator
  • Light\Filesystem\Node\Node - Polymorphic interface for files and folders
  • Light\Controller\FileSystemController - GraphQL mutation endpoint
  • Light\Type\Filesystem - GraphQL query endpoint

Related Pages:

  • Page 5: Authentication and authorization for file operations
  • Page 4.3.3: FileSystemController GraphQL mutations
  • Page 8.1: Config model for filesystem configuration storage

Sources: src/Filesystem/Node/Node.php1-24 src/Type/Filesystem.php1-198 src/Controller/FileSystemController.php1-364


7.1 Filesystem Architecture

The filesystem architecture consists of three layers: the storage abstraction layer (MountManager), the domain model layer (Node types), and the GraphQL API layer.

MountManager Pattern

The League\Flysystem\MountManager serves as the central abstraction layer, coordinating multiple storage backends (called "filesystems" or "drives"). Each drive is identified by a name prefix in location strings using the format: driveName://path/to/file.

Initialization in App Class:

src/App.php134-146

The MountManager is instantiated in the Light\App constructor and registered in the dependency injection container for autowiring into GraphQL resolvers.

Sources: src/App.php134-146 src/App.php149-152

Configuration Loading

Filesystem configurations are stored in the Config model where name = "fs". The App::getFSConfig() method retrieves these configurations with a default local filesystem fallback:

src/App.php695-714

Each configuration object contains:

  • name: Drive identifier for location strings
  • type: Backend type (local, s3, oss, hostlink, ftp)
  • data: Backend-specific configuration options
  • uuid: Unique identifier for CRUD operations

Sources: src/App.php695-714

Dynamic Adapter Loading

The App::getFS() method instantiates Flysystem adapters based on configuration type, with conditional support based on Composer package availability:


Adapter Factory Implementation:

The method uses a switch statement to instantiate the appropriate adapter based on the type field:

src/App.php717-787

Sources: src/App.php59-147 src/App.php695-787

Location String Format

All file operations use location strings with the drive name as a URI scheme:

<driveName>://<path>

Examples:

  • local://uploads/image.jpg
  • s3://public/documents/report.pdf
  • oss://media/video.mp4

The getPath() method in Node implementations strips the drive prefix:

src/Filesystem/Node/File.php29-39

Sources: src/Filesystem/Node/File.php29-39 src/Filesystem/Node/Folder.php39-43


7.2 Node Types (File and Folder)

The Node interface defines a polymorphic contract for filesystem objects, enabling type-safe GraphQL queries that return either File or Folder instances.

Node Interface

The filesystem architecture consists of three primary layers: the GraphQL API layer, the domain model layer with polymorphic Node types, and the storage abstraction layer powered by MountManager.

MountManager Role

The file storage system is built on three foundational layers:

Storage Abstraction Layer

The League\Flysystem\MountManager serves as the core abstraction layer, enabling multiple storage backends (called "filesystems" or "drives") to be accessed through a unified API. Each drive is identified by a name prefix in the location string format: driveName://path/to/file.

The MountManager is initialized in the Light\App constructor and registered in the dependency injection container:

src/App.php134-146

Sources: src/App.php134-146 src/App.php149-152

Configuration Loading

Filesystem configurations are retrieved from the Config model where name = "fs". The App::getFSConfig() method handles configuration loading with a default local filesystem if none is configured:

src/App.php695-714

The method returns an array of filesystem configuration objects, each containing:

  • name: Drive identifier used in location strings
  • type: Backend type (local, s3, oss, hostlink, ftp)
  • data: Backend-specific configuration options

Sources: src/App.php695-714

Dynamic Adapter Loading

The App::getFS() method instantiates the appropriate Flysystem adapter based on the filesystem type. Each backend type has conditional support based on whether the required Composer package is installed:

Architecture Diagram


Sources: src/App.php59-147 src/App.php695-787

Location String Format

All file operations use a location string format with the drive name as a prefix:

<driveName>://<path>

Examples:

  • local://uploads/image.jpg
  • s3://public/documents/report.pdf
  • oss://media/video.mp4

The getPath() method on Node objects strips the drive prefix and returns just the path portion.

Sources: src/Filesystem/Node/File.php29-39 src/Filesystem/Node/Folder.php39-43


Node Types (File and Folder)

Node Interface

The Node interface defines the common contract for all file system objects. It is marked with GraphQLite's #[Type] annotation, making it a GraphQL interface type that enables polymorphic queries.

Interface Definition


The interface declares four required methods:

src/Filesystem/Node/Node.php10-24

All methods are annotated with #[Field] to expose them in the GraphQL schema.


Sources: src/Filesystem/Node/Node.php1-24

File Class

The File class represents individual files and provides access to file content, metadata, and public URLs.

The File class represents individual files and provides access to file content, metadata, and public URLs.

Constructor:

src/Filesystem/Node/File.php15-21

The constructor accepts a location string and optional $metadata array. When provided, metadata avoids redundant filesystem operations during directory listings:

src/Filesystem/Node/File.php48-54

GraphQL Fields:

FieldReturn TypeDescription
nameString!Filename extracted via basename()
pathString!Path without drive prefix
locationString!Full location with drive prefix
sizeInt!File size in bytes
contentString!Raw file contents
base64ContentString!Base64-encoded contents
lastModifiedInt!Unix timestamp
mimeTypeString!MIME type (e.g., image/jpeg)
publicUrlStringPublic HTTP URL or fallback /api/uploads/ path

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

Folder Class

The Folder class represents directories and provides recursive traversal capabilities.

The Folder class represents directories and provides recursive traversal capabilities.

Constructor:

src/Filesystem/Node/Folder.php14-17

GraphQL Fields:

FieldReturn TypeDescription
nameString!Folder name from basename()
pathString!Path without drive prefix
locationString!Full location with drive prefix
lastModifiedInt!Unix timestamp of last modification
children[Node!]!Array of File and Folder objects
totalSizeInt!Recursive sum of all file sizes

Children Resolution:

The getChildren() method returns a polymorphic array of Node objects:

src/Filesystem/Node/Folder.php56-84

Key behaviors:

  • Skips hidden files (starting with .)
  • Returns shallow listing (non-recursive)
  • Instantiates Folder for directories, File for files
  • Pre-populates metadata cache for performance

Total Size Calculation:

The getTotalSize() method recursively traverses all descendants:

src/Filesystem/Node/Folder.php21-30

This uses listContents(..., true) to recursively list all files and sum their sizes.

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


7.3 Storage Backends

The system supports five storage backend types with dynamic adapter loading based on Composer package availability. Backends are auto-detected using Composer\InstalledVersions::isInstalled().

Supported Adapters

The following table lists all supported storage backends:

Backend TypeAdapter ClassComposer PackageAlways Available
localLeague\Flysystem\Local\LocalFilesystemAdapter(built-in)Yes
s3League\Flysystem\AwsS3V3\AwsS3V3Adapterleague/flysystem-aws-s3-v3No
ossAlphaSnow\Flysystem\Aliyun\*alphasnow/aliyun-oss-flysystemNo
hostlinkHL\Storage\Adapterhostlink/hostlink-storage-adapterNo
ftpLeague\Flysystem\Ftp\FtpAdapterleague/flysystem-ftpNo

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

Adapter Detection


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

Configuration Options by Backend

The Filesystem::getTypes() method returns metadata about available backend types, including their configuration options and whether they are disabled due to missing packages:

BackendLabelPackage RequirementConfiguration Options
localLocal Filesystem(always available)location, public_url
s3Amazon S3league/flysystem-aws-s3-v3region, endpoint, bucket, access_key, secret_key, prefix, public_url
ossAliyun OSSalphasnow/aliyun-oss-flysystemaccess_key_id, access_key_secret, endpoint, bucket, public_url
hostlinkHostlink Storagehostlink/hostlink-storage-adaptertoken, endpoint, public_url
ftpFTP Serverleague/flysystem-ftphost, username, password, port, root, public_url

src/Type/Filesystem.php31-107

Each backend type definition includes:

  • label: Human-readable name
  • name: Type identifier
  • disable: Boolean indicating if required package is missing
  • options: Map of configuration field definitions

Sources: src/Type/Filesystem.php31-107

Backend-Specific Implementations

Local Filesystem

Implementation in src/App.php723-742

Configuration example:


The local adapter uses PortableVisibilityConverter to set file/directory permissions (0640 for files, 0777 for directories).

Sources: src/App.php723-742 src/Type/Filesystem.php35-44

Amazon S3

Implementation in src/App.php749-778

Configuration example:


The S3 adapter uses AWS SDK v3 client with path-style endpoint support.

Sources: src/App.php749-778 src/Type/Filesystem.php48-61

Aliyun OSS

Implementation in src/App.php745-747

Uses the AliyunFactory to instantiate the filesystem from configuration data.

Sources: src/App.php745-747 src/Type/Filesystem.php78-89

Hostlink Storage

Implementation in src/App.php780-783

Requires token and endpoint configuration parameters.

Sources: src/App.php780-783 src/Type/Filesystem.php65-74

FTP Server

Configuration options defined in src/Type/Filesystem.php93-105

Requires host, username, password, with optional port (default 21) and root path.

Sources: src/Type/Filesystem.php93-105


7.4 File Operations API

The FileSystemController provides GraphQL mutations for file and folder operations.

Security Validation


Sources: src/Controller/FileSystemController.php34-364

Extension Blacklist

The system blocks 60+ dangerous file extensions defined in DISALLOW_EXT:

src/Controller/FileSystemController.php34

Blocked extensions include: php, exe, js, jsp, sh, py, vbs, bat, dll, etc.

Sources: src/Controller/FileSystemController.php34

Hidden File Protection

All operations reject files/folders starting with .:

src/Controller/FileSystemController.php40-45

This prevents manipulation of system files like .htaccess, .env, etc.

Sources: src/Controller/FileSystemController.php40-45 src/Controller/FileSystemController.php57-62 src/Controller/FileSystemController.php97-102

Folder Operations

Create Folder


Permissions: fs.folder:create

Implementation: src/Controller/FileSystemController.php36-51

Event: FolderCreating - allows modification of location before creation

Sources: src/Controller/FileSystemController.php36-51

Delete Folder


Permissions: fs.folder:delete

Implementation: src/Controller/FileSystemController.php53-68

Event: FolderDeleting - allows cancellation or logging

Sources: src/Controller/FileSystemController.php53-68

Rename Folder


Permissions: fs.folder:rename

Implementation: src/Controller/FileSystemController.php70-91

Event: FolderRenaming - allows modification of newName

Sources: src/Controller/FileSystemController.php70-91

File Operations

Write File


Permissions: fs.file:write

Implementation: src/Controller/FileSystemController.php93-108

Event: FileWriting - allows content modification or validation

Sources: src/Controller/FileSystemController.php93-108

Delete File


Permissions: fs.file:delete

Implementation: src/Controller/FileSystemController.php110-125

Event: FileDeleting - allows cancellation or cleanup

Sources: src/Controller/FileSystemController.php110-125

Rename File


Permissions: fs.file:rename

Validation: Checks extension against DISALLOW_EXT

Implementation: src/Controller/FileSystemController.php127-155

Event: FileRenaming - allows modification of newName

Sources: src/Controller/FileSystemController.php127-155

Move Node


Permissions: fs.node:move

Behavior: Automatically appends source filename to destination path if destination ends with /

Implementation: src/Controller/FileSystemController.php157-186

Event: NodeMoving - allows modification of from/to locations

Sources: src/Controller/FileSystemController.php157-186

Upload Operations

Upload Base64


Permissions: fs.file:write

Features:

  • Supports data URI format with MIME type prefix
  • Supports raw base64 strings
  • Returns File object for immediate UI update

Implementation: src/Controller/FileSystemController.php189-229

Sources: src/Controller/FileSystemController.php189-229

Upload Multipart


Permissions: fs.file:write

Parameters:

  • location: Target folder path
  • file: UploadedFileInterface from PSR-7
  • rename: If true, auto-renames on conflict (e.g., file.txtfile (1).txt)

Auto-rename Logic: src/Controller/FileSystemController.php264-275

Implementation: src/Controller/FileSystemController.php231-262

Sources: src/Controller/FileSystemController.php231-262 src/Controller/FileSystemController.php264-275

Event System

All mutations dispatch events before execution, allowing plugins to:

  • Validate operations
  • Modify parameters
  • Cancel operations (by throwing exceptions)
  • Log activity
  • Trigger webhooks

Available events:

  • FolderCreating / FolderDeleting / FolderRenaming
  • FileWriting / FileDeleting / FileRenaming
  • NodeMoving
  • FileUploading

Sources: src/Controller/FileSystemController.php10-17 src/Controller/FileSystemController.php36-262


7.5 Filesystem Configuration Management

Configuration Storage

Filesystem configurations are stored in the Config model with name = "fs". The value field contains a JSON array of filesystem objects, each with a unique UUID for identification.

Configuration Object Structure

Each filesystem configuration object has the following structure:


Sources: src/Controller/FileSystemController.php318-331

CRUD Operations


Sources: src/Controller/FileSystemController.php278-363 src/Type/Filesystem.php18-108

List Filesystems Query

Query all configured filesystems:


Implementation: src/Type/Filesystem.php18-25

Returns the JSON-decoded array from Config::Value("fs", "[]").

Sources: src/Type/Filesystem.php18-25

Get Available Types Query

Query backend types with their configuration schemas:


Implementation: src/Type/Filesystem.php31-108

Returns an array of backend type definitions with disable flags based on package availability.

Sources: src/Type/Filesystem.php31-108

Add Filesystem Mutation


Permissions: filesystem.add

Behavior: Auto-generates UUID using Uuid::uuid4()->toString()

Implementation: src/Controller/FileSystemController.php313-331

Sources: src/Controller/FileSystemController.php313-331

Update Filesystem Mutation


Permissions: filesystem.update

Behavior: Finds filesystem by UUID and replaces entire configuration object

Implementation: src/Controller/FileSystemController.php278-308

Sources: src/Controller/FileSystemController.php278-308

Delete Filesystem Mutation


Permissions: filesystem.delete

Behavior: Filters out the filesystem with matching UUID from the configuration array

Implementation: src/Controller/FileSystemController.php346-363

Sources: src/Controller/FileSystemController.php346-363

Query Operations

The Filesystem type provides query operations for browsing and searching files.

Node Query


Returns a Node (File or Folder) for the given location, or null if it doesn't exist.

Implementation: src/Type/Filesystem.php111-119

Sources: src/Type/Filesystem.php111-119

Exists Check


Returns boolean indicating whether the file or folder exists.

Implementation: src/Type/Filesystem.php122-125

Sources: src/Type/Filesystem.php122-125

Recursive Search


Parameters:

  • search: Keyword filter (case-insensitive substring match)
  • label: MIME type category filter (image, video, audio, document)

Behavior:

  • Recursively searches all configured filesystems
  • Skips hidden files (starting with .)
  • Returns heterogeneous array of File and Folder nodes

Label Matching: src/Type/Filesystem.php181-196

LabelMIME Types
imageimage/*
videovideo/*
audioaudio/*
documentapplication/pdf, application/msword, text/plain, application/vnd.ms-excel, application/vnd.ms-powerpoint

Implementation: src/Type/Filesystem.php131-176

Sources: src/Type/Filesystem.php131-196

Refresh this wiki

On this page