Download the PHP package wiserwebsolutions/laravel-lobbyist without Composer

On this page you can find all versions of the php package wiserwebsolutions/laravel-lobbyist. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-lobbyist

Laravel Lobbyist

Search, monitor, and summarize legislative activity — bills, votes, and elected representatives — across the United States, through a single driver-agnostic API.

This is the core package. It ships the contract, the driver manager, and the normalized data objects, but no data source of its own. You install one or more driver packages that plug in behind it:

Package Role
wiserwebsolutions/laravel-lobbyist-legiscan Default nationwide driver (LegiScan API)
wiserwebsolutions/laravel-lobbyist-palegis Pennsylvania driver (palegis.us RSS feeds)

There's also an optional add-on, layered on top of whichever drivers you install rather than replacing them:

Package Role
wiserwebsolutions/laravel-lobbyist-ai AI layer (Laravel AI SDK): bill summarization, classification, a tool-using Q&A agent, and semantic search

Installation

Publish the config if you want to change the default driver:

Usage

Lobbyist::state($abbr) resolves the driver registered for that state, falling back to the default driver (legiscan) when no state-specific driver is installed. The returned object is scoped to that state.

Which operations a driver supports varies by source — check first (see below).

Chambers

Every driver also exposes its state's legislative chambers as a fluent, chamber-scoped entry point. Each chamber delegates back to the driver's bills()/votes()/legislators() and filters the result to that chamber — so you never have to call ->byChamber() yourself:

(A chamber's own representatives() always means "the legislators belonging to this chamber" — for the Senate ChamberContext that's the same members $pa->senators() returns; only the driver-level representatives() means "House members specifically".)

chambers() defaults to [House, Senate] for every driver (bicameral, which covers all currently shipped drivers). Calling a chamber-scoped method the driver doesn't back throws UnsupportedOperationException, exactly like calling it directly on the driver.

Each chamber also exposes its computed political lean(), based on the party affiliation of its representatives:

The label compares the two major parties' share of the two-party total (independents/others are excluded from the comparison, but included in detail()): a spread under 10 points is "Neutral", 10–30 points is "Slight {Party}", and over 30 points is "Strong {Party}". lean() throws UnsupportedOperationException under the same condition as this chamber's representatives(), since it's built from that same data.

Sessions

Every driver also exposes the most recent legislative session directly:

Throws UnsupportedOperationException if the driver doesn't implement SessionProvider, or a LobbyistException if it does but reports no sessions at all.

Capabilities

Not every data source supports every operation — an RSS feed can list current bills but cannot look up an arbitrary bill by id. Drivers therefore implement only the capabilities they can back, and you can check before calling:

Calling an unsupported lookup throws UnsupportedOperationException.

Capability Method Interface LegiScan PA (RSS)
ListSessions sessions() SessionProvider ✅ ✅
ListBills bills() BillProvider ✅ ✅
GetBill bill($id) BillLookup ✅ ✅
ListVotes votes() VoteProvider — ✅
GetVote vote($id) VoteLookup ✅ —
ListLegislators senators() / representatives() / legislators() LegislatorProvider ✅ ✅
GetRepresentative representative($id) RepresentativeLookup ✅ —
GetBillText billText($id) BillTextLookup ✅ ✅
ListBillTextHistory billTextHistory($id) BillTextHistoryLookup ✅ ✅
GetBillTextVersion billTextVersion($textId) BillTextVersionLookup ✅ —
ListBillVotes votesForBill($id) BillVoteProvider ✅ —
ListBillChanges billChanges() BillChangeProvider ✅ —
ListSponsoredBills sponsoredBills($personId) SponsoredBillProvider ✅ —
ListCommitteeAssignments committeeAssignments() CommitteeAssignmentProvider — ✅
ListCommitteeMeetings committeeMeetings() CommitteeScheduleProvider — ✅
ListChamberSessionDays chamberSessionDays() ChamberSessionScheduleProvider — ✅
ListDatasets datasets() DatasetProvider ✅ —
GetDataset dataset($session) DatasetLookup ✅ —

Bill text

billText($id) returns the bill's current (most recent) text version; billTextHistory($id) returns every version (introduced, amended, enrolled, etc.) as a BillTextCollection:

content is null whenever a driver only has a link to the document (e.g. a PDF) rather than its fetched bytes — fetch url yourself in that case. BillTextCollection::latest() picks the most recent entry by date, which is what billText() is typically built from.

Every Bill a driver returns also carries the same version data directly, no driver call required — a mapper embeds it while building the Bill in the first place:

Bill::text()/texts() are pure reads of whatever the mapper already attached — they never perform I/O themselves, so toString() throws unless a driver already populated content (which billText($id) does, fetching just the latest version's bytes). toHTML()/toPDF() throw only when that particular version doesn't have a link in that format at all.

Bill votes, changes, and sponsorship

A Bill carries three more relations, each backed by its own optional capability rather than by bills()/bill() — a driver that can't answer the state-wide question can often still answer the bill-scoped one:

memo is the circulated "please join me on this bill" notice a sponsor files before (or alongside) introduction. Where a source publishes it — Pennsylvania does, as a Co-Sponsorship Memo — its subject reads as a plain-language title, and it is often the only human summary a bill has before its text is drafted. Drivers map it to meta['memo']/meta['memo_url']; both are null on sources with no such concept, so consumers should fall back to title.

Each entry in sponsors() carries its sponsor_type (a SponsorType, e.g. Primary/CoSponsor) and sponsor_order under meta, since sponsorship describes the relationship to this bill rather than an attribute of the member.

votesForBill($id) and sponsoredBills($personId) hit the driver directly when you don't already have a Bill in hand; billChanges() returns bills in the cheapest form the source offers (just enough to read changeHash), so a sync can skip fetching full detail for anything that hasn't moved since the last run.

A Vote's positions() gives the per-legislator record behind a roll call's yea/nay totals:

Committees

committeeAssignments() is keyed by seat (one row per legislator per committee), since that's how sources publish rosters — not by committee with a members list. position ("Chair", "Vice Chair", ...) stays a free-text string rather than an enum, since chambers invent titles a package can't anticipate; use isChair()/isViceChair() rather than comparing it directly. committeeMeetings()'s time is a string for the same reason: sources publish things like "Off the Floor" alongside actual clock times, and each entry has isUpcoming().

Chamber session days

Distinct from a committee schedule (when a committee meets) and a bill's own floor calendar (that a session day is coming, not which one) — this is the dated list of when the chamber itself is, or was, in session. Each entry's votingDay flags non-voting days where a source distinguishes them, and isUpcoming() checks the date against now.

Bulk datasets

Sources that meter by request count make per-record fetching the dominant cost of a sync. Where supported, a driver can hand back one archive covering an entire session instead:

Every accessor is a LazyCollection so importing a session of thousands of bills and roll calls doesn't load it all into memory at once, and iteration is repeatable — reading bills() then votes() re-walks the archive rather than consuming it. The trade-off is freshness: archives are rebuilt on the source's own schedule, so pair this with billChanges() for timely change detection between imports.

AI layer

wiserwebsolutions/laravel-lobbyist-ai is an optional consumer of the driver surface above (not a driver itself, so core stays dependency-free), built on the first-party Laravel AI SDK:

The Q&A agent's tools guard every call behind the driver's supports(Capability) check, so it degrades honestly instead of inventing an answer for a capability the state's driver doesn't back.

Data objects

Drivers return normalized spatie/laravel-data objects — Session, Bill, Vote, Legislator — regardless of source. States are typed via the StateEnum, chambers via Chamber, parties via Party.

These objects are provider-agnostic: each derives its typed properties from a documented, normalized meta array (see the class docblocks for the recognized keys) and is unaware of any specific data source. It is a driver's job to map its raw payload into that shape — so adding a new provider never requires touching core. Drivers typically keep the raw payload under meta['raw'] so nothing is lost.

Writing a state driver

  1. Create a package that requires wiserwebsolutions/laravel-lobbyist.
  2. Write a driver extending WiserWebSolutions\Lobbyist\Support\AbstractDriver and implementing the provider/lookup interfaces you can actually back. AbstractDriver derives capabilities()/supports() from those interfaces automatically and throws UnsupportedOperationException for lookups you omit. It also gives you chambers() for free, defaulting to [House, Senate]; override the protected $chambers property if your state has a unicameral legislature. session() and each chamber's lean() are also free, built on top of sessions()/legislators() — implement SessionProvider/LegislatorProvider and both work automatically.
  3. Map your source's raw payloads into the core DTOs' normalized meta shape — keep this in a mapper class in your package (see LegiscanMapper / PalegisMapper for reference). Core never learns about your source.
  4. Register it from your service provider's boot(), order-independently:

  5. Verify compliance with the shipped WiserWebSolutions\Lobbyist\Testing\AssertsDriverContract trait.

Testing

License

MIT © Daniel Wiser


All versions of laravel-lobbyist with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
illuminate/support Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
spatie/laravel-data Version ^4.20
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package wiserwebsolutions/laravel-lobbyist contains the following files

Loading the files please wait ...