PageSourceSearch

https://docs.phpvms.net/assets/js/e6242eb2.0f124a25.js

js phpvms.net collected 2026-10-04 13:24:44 UTC 18,022 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkphpvms_docs=self.webpackChunkphpvms_docs||[]).push([[4775],{97068(e,r,n){n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"guides/deeper-dive","title":"Deeper Dive","description":"Per-entity reference. Each section covers what an entity is, the fields you\'ll","source":"@site/docs/guides/deeper-dive.md","sourceDirName":"guides","slug":"/guides/deeper-dive","permalink":"/8.x/guides/deeper-dive","draft":false,"unlisted":false,"editUrl":"https://github.com/phpvms/docs/tree/master/docs/guides/deeper-dive.md","tags":[],"version":"current","frontMatter":{"id":"deeper-dive","title":"Deeper Dive","sidebar_label":"Deeper Dive"},"sidebar":"docs","previous":{"title":"Key Concepts","permalink":"/8.x/guides/basics"},"next":{"title":"Glossary","permalink":"/8.x/guides/glossary"}}');var i=n(74848),t=n(28453);const l={id:"deeper-dive",title:"Deeper Dive",sidebar_label:"Deeper Dive"},a="Deeper Dive",d={},c=[{value:"Airline",id:"airline",level:2},{value:"Airport",id:"airport",level:2},{value:"Subfleet",id:"subfleet",level:2},{value:"Aircraft",id:"aircraft",level:2},{value:"Fare",id:"fare",level:2},{value:"Rank",id:"rank",level:2},{value:"Flight",id:"flight",level:2},{value:"Flight types (IATA SSIM)",id:"flight-types-iata-ssim",level:3},{value:"PIREP",id:"pirep",level:2},{value:"Bid",id:"bid",level:2},{value:"Award",id:"award",level:2},{value:"User",id:"user",level:2}];function o(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r.header,{children:(0,i.jsx)(r.h1,{id:"deeper-dive",children:"Deeper Dive"})}),"\n",(0,i.jsx)(r.p,{children:"Per-entity reference. Each section covers what an entity is, the fields you'll\nconfigure, and how it connects to other entities."}),"\n",(0,i.jsxs)(r.p,{children:["For the high-level overview of how these fit together, see\n",(0,i.jsx)(r.a,{href:"/8.x/guides/basics",children:"Key Concepts"}),". For tricky terminology, see the\n",(0,i.jsx)(r.a,{href:"/8.x/guides/glossary",children:"Glossary"}),"."]}),"\n",(0,i.jsx)(r.h2,{id:"airline",children:"Airline"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    AL((Airline))\n    AL --\x3e SF[Subfleets]\n    AL --\x3e FL[Flights]\n    AL --\x3e US[Users<br/>pilots]\n    style AL fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsx)(r.p,{children:"Container for everything: flights, aircraft (via subfleets), and pilots. You\nneed at least one. Pilots pick an airline at registration, and most resources\nscope to it."}),"\n",(0,i.jsxs)(r.p,{children:["Key fields: ICAO code (3 letters, e.g. ",(0,i.jsx)(r.code,{children:"BAW"}),"), IATA code (2 letters, e.g. ",(0,i.jsx)(r.code,{children:"BA"}),"),\nname, callsign."]}),"\n",(0,i.jsx)(r.p,{children:"You can run multi-airline VAs \u2014 pilots register under one, and admins can\ntransfer them later."}),"\n",(0,i.jsx)(r.h2,{id:"airport",children:"Airport"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    AP((Airport))\n    AP -.optional base.-> SF[Subfleets]\n    AP -.dpt / arr / alt.-> FL[Flights]\n    AP -.home / current.-> US[Users]\n    AP -.location.-> AC[Aircraft]\n    style AP fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["Every airport in your network. Mark airports as ",(0,i.jsx)(r.strong,{children:"hubs"})," to make them selectable\nas a pilot's home base."]}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsxs)(r.li,{children:["ICAO is the primary key (e.g. ",(0,i.jsx)(r.code,{children:"EGLL"}),")."]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.code,{children:"hub"})," is a boolean flag \u2014 non-hub airports are still usable as flight\ndeparture/arrival points; the flag only controls whether pilots can pick them\nat registration."]}),"\n",(0,i.jsx)(r.li,{children:"Subfleets can optionally be based at a specific hub airport."}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"subfleet",children:"Subfleet"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    AL[Airline] --\x3e SF\n    AP[Hub Airport<br/>optional] -.base.-> SF\n    SF((Subfleet)) --\x3e AC[Aircraft]\n    SF -.allowed fares.-> FA[Fares]\n    SF -.allowed ranks.-> RK[Ranks]\n    SF -.required.-> TR[Type Ratings]\n    SF -.referenced by.->
1 FL[Flights]\n    style SF fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["The most important abstraction in phpvms. A subfleet is a ",(0,i.jsx)(r.strong,{children:"named group of\naircraft"})," that share fares, ranks, and (optionally) a base hub."]}),"\n",(0,i.jsx)(r.p,{children:'Think of it as how a real airline groups its fleet operationally \u2014 British\nAirways\' "767-336ER RR RB211 short-haul Y-class" is a subfleet, and so is\n"777-200ER GE90 long-haul J/Y".'}),"\n",(0,i.jsx)(r.p,{children:"A subfleet defines:"}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Type"})," (an arbitrary code, e.g. ",(0,i.jsx)(r.code,{children:"B763-LH-FJY"}),")"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Name"})," (human label)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Airline"})," it belongs to"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Hub airport"})," (optional \u2014 restricts where its aircraft are based)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Fuel type, cargo capacity"})," (operational defaults)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Allowed Fares"})," (M2M \u2014 you can override price/cost/capacity per subfleet\nwithout creating duplicate Fare records)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Allowed Ranks"})," (M2M \u2014 only pilots at these ranks can fly this subfleet,\nwith per-rank ACARS and manual pay rates)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Required Type Ratings"})," (M2M \u2014 pilots need the rating to fly)"]}),"\n"]}),"\n",(0,i.jsx)(r.p,{children:"You can have as many subfleets as you want with as much overlap as you need."}),"\n",(0,i.jsx)(r.h2,{id:"aircraft",children:"Aircraft"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    SF[Subfleet] --\x3e AC\n    AP[Airport<br/>current location] -.parked at.-> AC\n    AC((Aircraft))\n    AC -.flown in.-> PR[PIREPs]\n    AC -.reserved by.-> BD[Bids]\n    style AC fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["A specific airframe \u2014 a tail number, an ICAO type, and a current location. Every\naircraft belongs to ",(0,i.jsx)(r.strong,{children:"exactly one subfleet"}),", which is how it inherits fares,\nallowed ranks, and required type ratings."]}),"\n",(0,i.jsxs)(r.p,{children:["Key fields: registration (",(0,i.jsx)(r.code,{children:"G-CIVA"}),"), ICAO (",(0,i.jsx)(r.code,{children:"B744"}),"), name, status, condition,\ncurrent airport."]}),"\n",(0,i.jsx)(r.p,{children:"Aircraft track their own state: which airport they're parked at, hours flown,\ncondition (so you can model maintenance if you enable it)."}),"\n",(0,i.jsx)(r.h2,{id:"fare",children:"Fare"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    FA((Fare))\n    FA -.attached to.-> SF[Subfleets<br/>defaults]\n    FA -.overridden on.-> FL[Flights<br/>overrides]\n    FA -.snapshot in.-> PF[PirepFare<br/>per PIREP]\n    style FA fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["A passenger or cargo class \u2014 ",(0,i.jsx)(r.code,{children:"Y"})," (Economy), ",(0,i.jsx)(r.code,{children:"J"})," (Business), ",(0,i.jsx)(r.code,{children:"F"})," (First), ",(0,i.jsx)(r.code,{children:"C"}),"\n(Cargo), etc. A fare has:"]}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Code"})," (e.g. ",(0,i.jsx)(r.code,{children:"Y"}),")"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Name"})," (e.g. ",(0,i.jsx)(r.code,{children:"Economy"}),")"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Type"})," \u2014 passenger or cargo"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Capacity, Price, Cost"})," \u2014 defaults that subfleets can override"]}),"\n"]}),"\n",(0,i.jsxs)(r.p,{children:["Fares are ",(0,i.jsx)(r.strong,{children:"shared across the system"}),' but their economics get overridden when\nattached to a subfleet, so you can have one global "Economy" fare and let each\nsubfleet set its own seat count and ticket price.']}),"\n",(0,i.jsx)(r.h2,{id:"rank",children:"Rank"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    RK((Rank))\n    RK -.gates.-> SF[Subfleets]\n    RK -.held by.-> US[Users]\n    RK --\x3e|defines| PAY[Pay rates<br/>acars_pay / manual_pay]\n    style RK fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsx)(r.p,{children:"A pilot's progression tier. Ranks unlock subfleets and can carry pay rates that\noverride the subfleet defaults."}),"\n",(0,i.jsx)(r.p,{children:"Each rank has:"}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Hours required"})," to reach it"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Allowed Subfleets"})," (M2M with ",(0,i.jsx)(r.code,{children:"subfleet_rank"})," pivot \u2014 ",(0,i.jsx)(r.code,{children:"acars_pay"})," and\n",(0,i.jsx)(r.code,{children:"manual_pay"})," columns let you set per-rank pay rates)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Auto-promote"})," flag (auto-advance pilots when they hit the hours)"]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"flight",children:"Flight"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    AL[Airline] --\x3e FL\n    AP[Airports<br/>dpt / arr / alt] -.routes.-> FL\n    FL((Flight))\n    FL -.allowed.-> SF[Subfleets]\n    FL -.fare overrides.-> FA[Fares]\n    FL -.bid on by.-> BD[Bids]\n    FL -.flown via.-> PR[PIREPs]\n    style FL fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsx)(r.p,{children:'The schedule template \u2014 what we used to call a "schedule" pre-v7. A flight is a\nroute an airline offers; pilots bid on it and file PIREPs against it.'}),"\n",(0,i.jsx)(r.p,{children:"A flight has:"}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Airline + flight number"})," (and optional code/leg if numbers collide)"]}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.strong,{children:"Departure / arrival / alternate airports"})}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Flight type"})," \u2014 IATA SSIM service code (most common: ",(0,i.jsx)(r.code,{children:"J"})," scheduled\npassenger, ",(0,i.jsx)(r.code,{children:"F"})," scheduled cargo, ",(0,i.jsx)(r.code,{children:"C"})," charter passenger)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Allowed Subfleets"})," (M2M \u2014 pilots see only aircraft from subfleets they're\nrank-permitted on)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Per-flight Fare overrides"})," (M2M ",(0,i.jsx)(r.code,{children:"flight_fare"})," \u2014 overrides the subfleet\ndefaults for this specific route)"]}),"\n",(0,i.jsxs)(r.li,{children:[(0,i.jsx)(r.strong,{children:"Active / visible"})," windows, day-of-week filters, distance, route string"]}),"\n"]}),"\n",(0,i.jsx)(r.h3,{id:"flight-types-iata-ssim",children:"Flight types (IATA SSIM)"}),"\n",(0,i.jsxs)(r.p,{children:["The most common, in ",(0,i.jsx)(r.strong,{children:"bold"}),":"]}),"\n",(0,i.jsxs)(r.table,{children:[(0,i.jsx)(r.thead,{children:(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.th,{children:"Code"}),(0,i.jsx)(r.th,{children:"Meaning"})]})}),(0,i.jsxs)(r.tbody,{children:[(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:(0,i.jsx)(r.strong,{children:"J"})}),(0,i.jsx)(r.td,{children:(0,i.jsx)(r.strong,{children:"Scheduled passenger \u2013 normal service"})})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:(0,i.jsx)(r.strong,{children:"F"})}),(0,i.jsx)(r.td,{children:(0,i.jsx)(r.strong,{children:"Scheduled cargo and/or mail"})})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:(0,i.jsx)(r.strong,{children:"C"})}),(0,i.jsx)(r.td,{children:(0,i.jsx)(r.strong,{children:"Charter \u2013 passenger only"})})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"A"}),(0,i.jsx)(r.td,{children:"Additional cargo/mail"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"E"}),(0,i.jsx)(r.td,{children:"Special VIP flight (FAA/government)"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"G"}),(0,i.jsx)(r.td,{children:"Additional flights \u2013 passenger normal service"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"H"}),(0,i.jsx)(r.td,{children:"Charter \u2013 cargo and/or mail"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"I"}),(0,i.jsx)(r.td,{children:"Ambulance"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"K"}),(0,i.jsx)(r.td,{children:"Training"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"M"}),(0,i.jsx)(r.td,{children:"Mail service"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"O"}),(0,i.jsx)(r.td,{children:"Charter requiring special handling"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"P"}),(0,i.jsx)(r.td,{children:"Positioning \u2013 non-revenue (ferry/delivery/demo)"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"T"}),(0,i.jsx)(r.td,{children:"Technical test"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"W"}),(0,i.jsx)(r.td,{children:"Military"})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"X"}),(0,i.jsx)(r.td,{children:"Technical stop"})]})]})]}),"\n",(0,i.jsx)(r.p,{children:"Flight numbers don't have to be globally unique \u2014 but if a duplicate is\ndetected, the create/edit fails unless you supply a route code or leg."}),"\n",(0,i.jsx)(r.h2,{id:"pirep",children:"PIREP"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    US[User] --\x3e|files| PR\n    FL[Flight<br/>optional] -.against.-> PR\n    AC[Aircraft] -.in.-> PR\n    AP[Airports] -.dpt / arr / alt.->
1 PR\n    PR((PIREP))\n    PR --\x3e|posts| JR[Journal entries]\n    PR --\x3e|snapshots| PF[PirepFare]\n    PR -.triggers.-> AW[Award checks]\n    style PR fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["A ",(0,i.jsx)(r.strong,{children:"pilot report"})," \u2014 what a pilot files after flying. This is the core\ntransaction in phpvms: it triggers finances, hour tracking, rank progression,\nand award checks."]}),"\n",(0,i.jsx)(r.p,{children:"A PIREP captures:"}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsx)(r.li,{children:"The Flight it was flown against (optional \u2014 pilots can file free-form PIREPs\nwithout a Flight)"}),"\n",(0,i.jsx)(r.li,{children:"Aircraft used, dpt/arr/alt airports"}),"\n",(0,i.jsx)(r.li,{children:"Block time, flight time, fuel used, distance, route"}),"\n",(0,i.jsxs)(r.li,{children:["Fare counts (",(0,i.jsx)(r.code,{children:"PirepFare"})," rows snapshot how many of each class were carried)"]}),"\n",(0,i.jsx)(r.li,{children:"Live ACARS position rows if a tracker was used"}),"\n",(0,i.jsx)(r.li,{children:"Journal transactions for revenue/fuel/pay/expenses"}),"\n"]}),"\n",(0,i.jsxs)(r.p,{children:["PIREPs go through a state machine: ",(0,i.jsx)(r.code,{children:"pending"})," \u2192 ",(0,i.jsx)(r.code,{children:"accepted"})," / ",(0,i.jsx)(r.code,{children:"rejected"})," \u2192\n",(0,i.jsx)(r.code,{children:"cancelled"}),". Acceptance is what posts the financial entries to the airline's\njournal."]}),"\n",(0,i.jsx)(r.h2,{id:"bid",children:"Bid"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    US[User] --\x3e|reserves| BD\n    FL[Flight] -.on.-> BD\n    AC[Aircraft] -.with.-> BD\n    BD((Bid))\n    style BD fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["A reservation. A pilot ",(0,i.jsx)(r.strong,{children:"bids"})," on a ",(0,i.jsx)(r.code,{children:"Flight + Aircraft"})," combination to lock it\nfor themselves before flying. Configurable: bids may be soft (advisory) or hard\n(block other pilots)."]}),"\n",(0,i.jsx)(r.h2,{id:"award",children:"Award"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    AW((Award))\n    AW -.qualifies via.-> CL[Award class<br/>app/Awards/ or custom]\n    AW -.earned by.-> US[Users]\n    PR[PIREP] -.triggers re-check.-> AW\n    style AW fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsxs)(r.p,{children:["Pluggable achievement system. Each award references a class (",(0,i.jsx)(r.code,{children:"ref_model_type"}),")\nthat decides if a user qualifies \u2014 examples ship in ",(0,i.jsx)(r.code,{children:"app/Awards/"})," and you can\nadd custom ones via modules. Earned awards appear on the pilot's profile."]}),"\n",(0,i.jsx)(r.h2,{id:"user",children:"User"}),"\n",(0,i.jsx)(r.mermaid,{value:"flowchart LR\n    AL[Airline] --\x3e US\n    RK[Rank] -.holds.-> US\n    AP[Airport<br/>home / current] -.based at.-> US\n    US((User))\n    US --\x3e|reserves| BD[Bids]\n    US --\x3e|files| PR[PIREPs]\n    US -.earns.-> AW[Awards]\n    US -.holds.-> TR[Type Ratings]\n    style US fill:#067ec1,stroke:#045887,color:#fff"}),"\n",(0,i.jsx)(r.p,{children:"A pilot. Belongs to an Airline, holds a Rank, has a home Airport (their hub),\nand a current Airport (where they last flew to). Users also carry type ratings\n(M2M) which gate access to subfleets that require specific ratings."})]})}function h(e={}){const{wrapper:r}={...(0,t.R)(),...e.components};return r?(0,i.jsx)(r,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},28453(e,r,n){n.d(r,{R:()=>l,x:()=>a});var s=n(96540);const i={},t=s.createContext(i);function l(e){const r=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.