PHPackages                             ernestdefoe/recruiting - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. ernestdefoe/recruiting

ActiveFlarum-extension[Utility &amp; Helpers](/categories/utility)

ernestdefoe/recruiting
======================

College football recruiting tracker for Flarum 2. Pulls live data from the College Football Data API (collegefootballdata.com) and renders a recruiting rankings page at /recruiting.

3.1.0(1w ago)043↓100%MITPHPPHP ^8.3CI passing

Since May 16Pushed 1w agoCompare

[ Source](https://github.com/ernestdefoe/recruiting)[ Packagist](https://packagist.org/packages/ernestdefoe/recruiting)[ Docs](https://github.com/ernestdefoe/recruiting)[ RSS](/packages/ernestdefoe-recruiting/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (10)Dependencies (2)Versions (19)Used By (0)

FBSFB Recruiting
================

[](#fbsfb-recruiting)

[![Floxum](https://camo.githubusercontent.com/aa8db26028f081235bb282d4535e5a4a552b91bb136b6c4e24ea19e285d08f2a/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f72656372756974696e672f62616467652f6e616d65)](https://floxum.com/extension/ernestdefoe/recruiting)[![Version](https://camo.githubusercontent.com/001de1bd0088dfcc8cdb218a67287a3def02e194ba1c2d4dd1c97eee546dfb51/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f72656372756974696e672f62616467652f686967686573742d76657273696f6e)](https://floxum.com/extension/ernestdefoe/recruiting)[![Downloads](https://camo.githubusercontent.com/d76149cf240d983547ce4aa9e850eb0d8c076bf670304f5c7c6dbbe27a814516/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f72656372756974696e672f62616467652f646f776e6c6f616473)](https://floxum.com/extension/ernestdefoe/recruiting)[![Review](https://camo.githubusercontent.com/5b0cfe4c80917e2eaf0f24f46c90c8ad9ae0caa3226ec7b9825cf853ede3a68b/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f72656372756974696e672f62616467652f726576696577)](https://floxum.com/extension/ernestdefoe/recruiting)[![License](https://camo.githubusercontent.com/d41a1c6a9d411e18cefab9db5afbce4a8ede28e333c02ad3fe2afd95b59243df/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f72656372756974696e672f62616467652f6c6963656e7365)](https://floxum.com/extension/ernestdefoe/recruiting)

A Flarum 2 extension that pulls live college football recruiting rankings from the [College Football Data API](https://collegefootballdata.com/) and displays them on a dedicated `/recruiting` page inside your Flarum forum.

[![Desktop view](docs/screenshot-desktop.png)](docs/screenshot-desktop.png)

---

Features
--------

[](#features)

- **Live data** — recruiting rankings pulled directly from the CFBD API and cached server-side
- **Player headshots** — automatically sourced from On3's football rankings page; falls back to a star-tier coloured initials avatar when no photo is available
- **Full player details** — national rank, star rating, numerical rating, position, height, weight, high school, hometown, and commitment status
- **Filters** — search by name / school / city, filter by position, filter by committed vs. undecided
- **Stats bar** — total recruits displayed, average rating, committed count
- **Responsive grid** — adapts from 4–5 columns on desktop down to 2 on mobile

Mobile view[![Mobile view](docs/screenshot-mobile.png)](docs/screenshot-mobile.png)---

Requirements
------------

[](#requirements)

- Flarum 2.x
- PHP 8.3+
- A free CFBD API key from [collegefootballdata.com](https://collegefootballdata.com/)
- `guzzlehttp/guzzle` ^7.0 (pulled in automatically via Composer)

---

Installation
------------

[](#installation)

```
composer require ernestdefoe/recruiting
php flarum migrate
php flarum cache:clear
```

Then enable the extension in **Admin → Extensions**.

---

Configuration
-------------

[](#configuration)

All settings are found in **Admin → Extensions → FBSFB Recruiting**.

SettingDescriptionDefault**API Key**Your CFBD bearer token*(required)***Recruiting Year**Class year to display (e.g. `2026`)Current calendar year**Team Filter**Show only recruits committed to a specific team (e.g. `Alabama`). Leave blank for national rankings.*(blank — national)***Page / Widget Title**Heading shown above the widget and on `/recruiting`. Leave blank for "Top Recruits".*(blank)***Max Recruits**How many recruits to display (1–100)`25`**Cache Duration**Soft TTL for CFBD responses (minutes). After this expires the next request serves the cached data and dispatches a background refresh — see [Caching &amp; refresh strategy](#caching--refresh-strategy).`360` (6 hours)---

How it works
------------

[](#how-it-works)

1. A forum member navigates to `/recruiting` (or clicks the **Recruiting** link in the sidebar nav).
2. The JS frontend calls the internal API route `GET /api/cfbd-recruits`.
3. The PHP controller reads your admin settings and checks Flarum's cache. If the cached payload is fresh it returns immediately. If it's past the soft TTL it dispatches a background refresh job and returns the cached (stale) data immediately — see [Caching &amp; refresh strategy](#caching--refresh-strategy).
4. The refresh job (`RefreshRecruitsJob`) proxies a request to `https://api.collegefootballdata.com/recruiting/players?year=…&team=…`, sorts results by national ranking, transforms them into the JSON shape, and writes the new payload back to the cache envelope.
5. Recruit records are enriched with On3 headshots (see below) and returned to the client.
6. Player cards are rendered with national rank, stars, headshot, physical measurements, high school, hometown, and commitment pill.
7. Client-side filters let users narrow by position, commitment status, or keyword search instantly without a second API call.

---

Caching &amp; refresh strategy
------------------------------

[](#caching--refresh-strategy)

The extension uses a **stale-while-revalidate** cache envelope so a CFBD round-trip (≤ 10 s) never blocks the user's request.

### Cache shape

[](#cache-shape)

```
ernestdefoe-recruiting. → { data: [...], fetched_at:  }

```

- **Hard retention:** 7 days. Stale data is still served if every refresh attempt fails — better than a blank widget during a CFBD outage.
- **Soft TTL:** the **Cache Duration** setting (default 6 hours). Determines when a request is treated as stale and triggers a background refresh.

### Refresh paths

[](#refresh-paths)

StateBehaviourFresh cache (within soft TTL)Return cached data. No network.Stale cache, no refresh in flightDispatch `RefreshRecruitsJob`, return cached data immediately. A 90 s "refreshing" lock prevents N concurrent requests from dispatching N jobs in a stampede.Stale cache, refresh already in flightReturn cached data immediately. The in-flight job will repopulate the cache for the next visitor.No cache at all (first request ever, or `cache:clear`)Inline CFBD fetch. This is the ONE request that pays the API round-trip on the request thread.### Recommended: run a queue worker

[](#recommended-run-a-queue-worker)

By default Flarum 2 ships with the **`sync` queue driver**, which means `RefreshRecruitsJob::dispatch()` runs inline in the request — defeating the point of the stale-while-revalidate pattern (one unlucky stale request per soft-TTL window still pays the CFBD cost).

For zero-wait refresh, configure a real queue driver in `config.php`:

```
'queue' => [
    'driver' => 'database',     // or 'redis', 'sqs', etc.
],
```

…then run a queue worker (typically under supervisor / systemd):

```
php flarum queue:work --tries=3 --timeout=60
```

With a real driver the dispatch returns in &lt;1 ms and the worker handles the CFBD fetch in the background. Every request — even the first one after the soft TTL expires — gets cached data instantly.

---

Player headshots
----------------

[](#player-headshots)

Headshots are sourced from **[On3](https://www.on3.com/)**, which maintains photos for thousands of current and historical high-school recruits.

### How the image lookup works

[](#how-the-image-lookup-works)

On3's football rankings page (`on3.com/rivals/rankings/player/football/{year}/`) is fully server-rendered HTML containing 150+ ranked recruits, each with a profile link and headshot image URL embedded directly in the markup.

On the first API call after the cache is empty the extension:

1. Fetches the On3 rankings page for the configured class year (one HTTP request).
2. Parses the HTML to build a **name → image URL** map using positional matching between profile hrefs (`/rivals/jared-curtis-159433/`) and `on3static.com` image paths.
3. Caches the map for **24 hours** — subsequent requests read from cache with zero external HTTP calls.
4. Matches each CFBD recruit to the map by normalised name slug (e.g. `"Jared Curtis"` → `"jared-curtis"`).

### Fallback avatars

[](#fallback-avatars)

When no On3 photo is available the card shows a coloured initials avatar whose background is coded by star rating:

StarsColour★★★★★Gold★★★★Blue★★★Green★★ / unratedSlate---

Player card data
----------------

[](#player-card-data)

Each card displays:

- **National ranking** (`#1`, `#2`, …)
- **Star rating** (★★★★★) and **numerical rating** (e.g. `0.9991`)
- **Headshot** — sourced from On3; coloured initials avatar as fallback
- **Name** and **position** (QB, WR, CB, OT, DE, …)
- **Height · Weight** (e.g. `6'3" · 215 lbs`)
- **High school** name
- **Hometown** (City, State)
- **Commitment pill** — `✔ Georgia` (green) or `○ Undecided` (grey)

---

Data sources
------------

[](#data-sources)

DataSourceRankings, ratings, recruit details[College Football Data API](https://collegefootballdata.com/)Player headshots[On3](https://www.on3.com/) rankings pageCFBD provides a free API key with generous rate limits. The extension caches all external responses to minimise outbound requests.

---

Support
-------

[](#support)

Questions, bug reports, and feature requests:

- **Support forum:**
- **Issues:**

License
-------

[](#license)

MIT

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance98

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

18

Last Release

10d ago

Major Versions

2.0.14 → 3.0.02026-05-26

### Community

Maintainers

![](https://www.gravatar.com/avatar/c9978664264055711c21fbcf73c937f758df771d9cb40f6a25370b10123e7abc?d=identicon)[ernestdefoe](/maintainers/ernestdefoe)

---

Top Contributors

[![ernestdefoe](https://avatars.githubusercontent.com/u/24905286?v=4)](https://github.com/ernestdefoe "ernestdefoe (36 commits)")

---

Tags

flarumrecruitingcollege footballgridironcfbd

### Embed Badge

![Health badge](/badges/ernestdefoe-recruiting/health.svg)

```
[![Health](https://phpackages.com/badges/ernestdefoe-recruiting/health.svg)](https://phpackages.com/packages/ernestdefoe-recruiting)
```

###  Alternatives

[fof/upload

The file upload extension for the Flarum forum with insane intelligence.

191185.4k17](/packages/fof-upload)[flarum-lang/russian

Russian language pack for Flarum.

12127.5k](/packages/flarum-lang-russian)[fof/byobu

Well integrated, advanced private discussions.

61112.4k10](/packages/fof-byobu)[fof/sitemap

Generate a sitemap

1896.4k2](/packages/fof-sitemap)[fof/webhooks

Automatically notify Discord, Slack, and Microsoft Teams when events happen on your Flarum forum.

2519.4k](/packages/fof-webhooks)[fof/discussion-language

Specify the language a discussion is written in &amp; sort by language

1032.0k](/packages/fof-discussion-language)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
