*/ public static function ladder(): array { return [self::Free, self::Pro]; } /** * Every paid tier — the ones a Pro build can be. There is one. * * Free is not one: a free install is not the bottom rung of Pro, it is the * whole product minus features it never carried (CONTEXT.md, Pro). * * @return list */ public static function paid(): array { return [self::Pro]; } /** Where this tier sits on the ladder. Higher is more. */ public function rank(): int { return (int) array_search($this, self::ladder(), true); } /** * Whether an install AT this tier supplies a member declared at `$other`. * * **Free is included by every tier**, which is what makes a Pro install * the whole product rather than a different one. */ public function includes(self $other): bool { return $this->rank() >= $other->rank(); } /** * Whether this install supplies the tier this member is declared at. * * Free is always supplied, so a member free declares needs nothing looked * up at all. */ public function isSuppliedBy(ProPresence $pro): bool { return $this === self::Free || $pro->installedTier()->includes($this); } }