Namespacing Loom73¶
The base namespace is:
Loom73 uses names inspired by the parts of a loom to describe broad architectural responsibilities. The metaphor provides orientation; concrete class names remain direct and technical.
Good:
Avoid names whose meaning depends on understanding an internal metaphor:
Principles¶
Loom73 namespaces follow a few rules:
Namespaces describe responsibility.
Reusable mechanisms stay separate from application decisions.
Application logic remains visible.
Simple behavior should not be abstracted merely to fit a namespace.
The namespace structure does not introduce a service container, plugin system or mandatory dependency-injection layer.
Autoloading¶
Loom73 currently uses its own autoloader.
A namespaced class such as:
is first resolved to:
If no matching library file exists, Loom73 searches the directories configured in LOOM73['directories'], including:
The fallback uses the class basename. Class names should therefore remain unique across these directories.
Application code does not have to live under lib/. A class may be physically application-specific while still using the namespace that best describes its responsibility.
For example:
application/controllers/UserCtrl.php
→ Loom73\Weave\Controllers\UserCtrl
application/models/User.php
→ Loom73\Beam\User
The first coordinates an HTTP request. The second performs persistence work for the application.
Loom73\Woodframe\¶
Woodframe contains the structural foundation shared by the rest of Loom73.
Current classes include:
Loom73\Woodframe\Config
Loom73\Woodframe\Ctrl
Loom73\Woodframe\Template
Loom73\Woodframe\Flash
Loom73\Woodframe\Logger
Loom73\Woodframe\Mailman
Loom73\Woodframe\OwnerRegistry
Loom73\Woodframe\Debugger
Loom73\Woodframe\Errata
Its responsibilities include:
configuration
base controller behavior
template composition
flash messages
mail delivery
operational logging
shared registries
debugging and error support
Woodframe should contain mechanisms that are useful across multiple parts of the application. Domain-specific decisions belong elsewhere.
Configuration¶
Module configuration files live in:
Each file returns an array. Config loads these files and exposes values through dot notation:
Config::get('database.default');
Config::get('yarn.storage_path');
Config::get('ledger.enabled', false);
OwnerRegistry¶
OwnerRegistry defines the logical entities that other components may reference:
Owners are wider than asset ownership. Yarn and Ledger may both consult the registry, so the registry belongs to Woodframe.
The dependency direction is:
Woodframe must not depend on Yarn or Ledger to understand what an owner is.
Loom73\Beam\¶
Beam is the persistence and data-access layer.
Current core classes include:
Concrete application models may also use the Beam namespace when their primary responsibility is data access.
Beam provides:
shared PDO connection handling
prepared statements
normalized query results
small CRUD primitives
identifier validation
soft-delete helpers
explicit SQL support
Beam is not an ORM and does not attempt to replace SQL with a universal query builder.
Connection¶
Connection::pdo() returns the shared PDO instance, creating it on first use.
Connection::make() creates an independent PDO connection from the configured database connection or from an explicitly supplied configuration array.
Connection::set() and Connection::reset() allow the shared connection to be replaced or cleared.
Connection::ping() prepares and executes SELECT 1. It is intended for operational health checks such as:
A connection health check returns a boolean. It is not a domain query and does not require a QueryResult.
Model¶
Model provides common operations such as:
getById
getBy
all
create
updateById
updateWhere
updateRawWhere
deleteById
softDeleteById
restoreById
getFields
Concrete models should write explicit SQL when a query expresses:
Values must be bound as parameters. Dynamic identifiers must pass through the identifier validation provided by Model.
QueryResult¶
Database operations return a QueryResult containing:
Typical usage:
$result = $this->User->getById($id);
if ($result->fails()):
// Handle the database failure.
endif;
if ($result->isEmpty()):
// The query succeeded but found no record.
endif;
$user = $result->first();
QueryResult represents query execution outcomes. Invalid API usage and programming errors may still throw exceptions.
Loom73\Heddle\¶
Heddle handles authentication, sessions and authorization.
Current classes include:
Its responsibilities include:
The base controller makes the authentication context available, but routes remain public until a controller explicitly applies a guard:
$this->requireAuth();
$this->requireAdmin();
$this->requireEditor();
$this->requireAbility('manage_users');
Heddle determines authentication and authorization state. Controllers decide which application actions require that state.
Loom73\Yarn\¶
Yarn manages uploaded files as application resources.
Current classes include:
Loom73\Yarn\Asset
Loom73\Yarn\AssetType
Loom73\Yarn\AssetValidator
Loom73\Yarn\AssetStorage
Loom73\Yarn\AssetPolicy
Loom73\Yarn\AssetUploader
Loom73\Yarn\AssetDelivery
Loom73\Yarn\AssetValidationResult
Loom73\Yarn\AssetUploadResult
Yarn owns:
upload validation
MIME and extension validation
storage outside the public web root
asset metadata
owner-slot policy
single-slot replacement
visibility
inline and attachment delivery
Yarn distinguishes between:
owner_type
logical kind of owning entity
owner_id
identifier of that entity
owner_slot
contextual position of the asset
asset_type
semantic file classification stored in the database
Example:
HTTP routing does not belong to Yarn. For example:
Yarn\AssetDelivery
validates and emits a file response
Weave\Controllers\AssetCtrl
handles the route, authentication and response choice
Loom73\Ledger\¶
Ledger records meaningful application actions.
Current classes include:
An event may record:
Examples of suitable actions:
Ledger is an audit trail. Operational failures belong to Woodframe\Logger.
A Ledger failure must not invalidate an application action that has otherwise completed successfully.
Loom73\Weave\¶
Weave is the application orchestration layer.
Controllers currently use:
Weave combines reusable Loom73 components into project-specific behavior:
request handling
controller actions
authorization decisions
model and service coordination
view preparation
redirects
JSON responses
binary responses
Reusable mechanisms belong to their core namespaces. Decisions about what the application does belong to Weave.
Loom73\Shuttle\¶
Shuttle contains command-line tooling.
The reusable CLI helper lives at:
Command classes live in:
and use the same namespace:
Shuttle handles tasks such as:
instance installation
health inspection
administrator creation
asset-type creation
Ledger cleanup
maintenance and diagnostics
Shuttle should remain a small command resolver and a collection of explicit commands rather than becoming a general console framework.
Dependency direction¶
The intended dependency flow is:
Woodframe
shared structure and registries
Beam
persistence primitives
Heddle
authentication and authorization
Yarn
asset lifecycle
Ledger
auditing
Weave
application orchestration
Shuttle
command-line operations across the instance
More concretely:
Weave may use Woodframe, Beam, Heddle, Yarn and Ledger.
Yarn may use Beam and Woodframe.
Ledger may use Beam and Woodframe.
Heddle may use Beam.
Core components must not depend on application controllers.
Naming discipline¶
The metaphor should make the architecture memorable without making the code cryptic.
Use direct class names:
In controllers, Loom73 distinguishes dependencies from runtime data:
$this->User; // model or service
$this->Asset; // model or service
$this->Auth; // reusable component
$user; // record or runtime value
$asset; // record or runtime value
$result; // operation result
This convention is intentional and should be applied consistently.
Summary¶
Woodframe structural foundation
Beam persistence
Heddle authentication and access
Yarn uploaded resources
Ledger audit trail
Weave application orchestration
Shuttle command-line operations
The governing rule remains:
Use namespaces to make responsibility legible.
Do not use them to make simple code look sophisticated.