Skip to main content
Version: v8.x

Deeper Dive

Per-entity reference. Each section covers what an entity is, the fields you'll configure, and how it connects to other entities.

For the high-level overview of how these fit together, see Key Concepts. For tricky terminology, see the Glossary.

Airline

Container for everything: flights, aircraft (via subfleets), and pilots. You need at least one. Pilots pick an airline at registration, and most resources scope to it.

Key fields: ICAO code (3 letters, e.g. BAW), IATA code (2 letters, e.g. BA), name, callsign.

You can run multi-airline VAs — pilots register under one, and admins can transfer them later.

Airport

Every airport in your network. Mark airports as hubs to make them selectable as a pilot's home base.

  • ICAO is the primary key (e.g. EGLL).
  • hub is a boolean flag — non-hub airports are still usable as flight departure/arrival points; the flag only controls whether pilots can pick them at registration.
  • Subfleets can optionally be based at a specific hub airport.

Subfleet

The most important abstraction in phpvms. A subfleet is a named group of aircraft that share fares, ranks, and (optionally) a base hub.

Think of it as how a real airline groups its fleet operationally — British Airways' "767-336ER RR RB211 short-haul Y-class" is a subfleet, and so is "777-200ER GE90 long-haul J/Y".

A subfleet defines:

  • Type (an arbitrary code, e.g. B763-LH-FJY)
  • Name (human label)
  • Airline it belongs to
  • Hub airport (optional — restricts where its aircraft are based)
  • Fuel type, cargo capacity (operational defaults)
  • Allowed Fares (M2M — you can override price/cost/capacity per subfleet without creating duplicate Fare records)
  • Allowed Ranks (M2M — only pilots at these ranks can fly this subfleet, with per-rank ACARS and manual pay rates)
  • Required Type Ratings (M2M — pilots need the rating to fly)

You can have as many subfleets as you want with as much overlap as you need.

Aircraft

A specific airframe — a tail number, an ICAO type, and a current location. Every aircraft belongs to exactly one subfleet, which is how it inherits fares, allowed ranks, and required type ratings.

Key fields: registration (G-CIVA), ICAO (B744), name, status, condition, current airport.

Aircraft track their own state: which airport they're parked at, hours flown, condition (so you can model maintenance if you enable it).

Fare

A passenger or cargo class — Y (Economy), J (Business), F (First), C (Cargo), etc. A fare has:

  • Code (e.g. Y)
  • Name (e.g. Economy)
  • Type — passenger or cargo
  • Capacity, Price, Cost — defaults that subfleets can override

Fares are shared across the system but their economics get overridden when attached to a subfleet, so you can have one global "Economy" fare and let each subfleet set its own seat count and ticket price.

Rank

A pilot's progression tier. Ranks unlock subfleets and can carry pay rates that override the subfleet defaults.

Each rank has:

  • Hours required to reach it
  • Allowed Subfleets (M2M with subfleet_rank pivot — acars_pay and manual_pay columns let you set per-rank pay rates)
  • Auto-promote flag (auto-advance pilots when they hit the hours)

Flight

The schedule template — what we used to call a "schedule" pre-v7. A flight is a route an airline offers; pilots bid on it and file PIREPs against it.

A flight has:

  • Airline + flight number (and optional code/leg if numbers collide)
  • Departure / arrival / alternate airports
  • Flight type — IATA SSIM service code (most common: J scheduled passenger, F scheduled cargo, C charter passenger)
  • Allowed Subfleets (M2M — pilots see only aircraft from subfleets they're rank-permitted on)
  • Per-flight Fare overrides (M2M flight_fare — overrides the subfleet defaults for this specific route)
  • Active / visible windows, day-of-week filters, distance, route string

Flight types (IATA SSIM)

The most common, in bold:

CodeMeaning
JScheduled passenger – normal service
FScheduled cargo and/or mail
CCharter – passenger only
AAdditional cargo/mail
ESpecial VIP flight (FAA/government)
GAdditional flights – passenger normal service
HCharter – cargo and/or mail
IAmbulance
KTraining
MMail service
OCharter requiring special handling
PPositioning – non-revenue (ferry/delivery/demo)
TTechnical test
WMilitary
XTechnical stop

Flight numbers don't have to be globally unique — but if a duplicate is detected, the create/edit fails unless you supply a route code or leg.

PIREP

A pilot report — what a pilot files after flying. This is the core transaction in phpvms: it triggers finances, hour tracking, rank progression, and award checks.

A PIREP captures:

  • The Flight it was flown against (optional — pilots can file free-form PIREPs without a Flight)
  • Aircraft used, dpt/arr/alt airports
  • Block time, flight time, fuel used, distance, route
  • Fare counts (PirepFare rows snapshot how many of each class were carried)
  • Live ACARS position rows if a tracker was used
  • Journal transactions for revenue/fuel/pay/expenses

PIREPs go through a state machine: pendingaccepted / rejectedcancelled. Acceptance is what posts the financial entries to the airline's journal.

Bid

A reservation. A pilot bids on a Flight + Aircraft combination to lock it for themselves before flying. Configurable: bids may be soft (advisory) or hard (block other pilots).

Award

Pluggable achievement system. Each award references a class (ref_model_type) that decides if a user qualifies — examples ship in app/Awards/ and you can add custom ones via modules. Earned awards appear on the pilot's profile.

User

A pilot. Belongs to an Airline, holds a Rank, has a home Airport (their hub), and a current Airport (where they last flew to). Users also carry type ratings (M2M) which gate access to subfleets that require specific ratings.

Need help?

Stuck on something or want to share what you've built? The community is active on the forum and GitHub.