Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Providence Bundle Laravel Package

survos/providence-bundle

A Symfony bundle from Survos that wires Providence services into your PHP application, with ready-made configuration, service definitions, and Twig helpers. Install via Composer, register the bundle in your kernel, and start using it.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the critical fact: survos/providence-bundle is a Symfony bundle, not a Laravel package. There is no ProvidenceServiceProvider, no facade, no config/providence.php to publish, and no illuminate/* contracts in its dependency graph. "CA" here means CollectiveAccess, and Providence is the name of CollectiveAccess's back-end cataloging application (as opposed to Pawtucket, its public front-end). The bundle's job is to let a Symfony app read/write CollectiveAccess profiles (the XML files that define metadata element sets, UI layouts, and relationship types) and talk to a Providence install.

With 0 stars and 0 dependents, treat this as read-the-source code experimental software. Your first hour should be reconnaissance, not installation:

  1. Open composer.json and note the Symfony version constraints and the providence/collectiveaccess peer dependencies. This alone will tell you whether it targets Symfony 4.x (likely, given the era of most Survos bundles) or something current.
  2. Read src/ top to bottom — at this scale the entire public API is probably 5–15 classes. Look for a ProvidenceClient, ProfileParser, or ProfileImporter type class; that is the real surface area.
  3. Check DependencyInjection/ and config/ (or Resources/config/) for the service definitions. The constructor arguments tell you what credentials, base URLs, and file paths are required.
  4. Look for a Command/ directory — Survos bundles habitually ship symfony/console commands, and a providence:import-profile style command is the fastest path to a first successful run.

Your first use case should be read-only: parse an existing Providence profile XML and list the metadata element codes it defines. Do not start with an import.

If you are committed to Laravel (i.e., this is a Laravel monolith and you are not introducing a Symfony kernel), do not fight the bundle. Wrap the underlying CollectiveAccess Providence web services API yourself instead. Every Providence install exposes a REST-ish endpoint at <providence_base>/service.php/ with model, find, and item operations, authenticated by a CA user's API key. A 60-line ProvidenceClient around Illuminate\Support\Facades\Http will get you 90% of the value with none of the framework mismatch:

// config/services.php
'providence' => [
    'base_url' => env('PROVIDENCE_URL'),   // e.g. https://ca.example.org/providence
    'api_key'  => env('PROVIDENCE_API_KEY'),
],

// app/Services/ProvidenceClient.php
public function find(string $table, array $criteria = [], int $limit = 50): array
{
    return Http::baseUrl(config('services.providence.base_url'))
        ->withHeaders(['X-API-Key' => config('services.providence.api_key')])
        ->acceptJson()
        ->get("service.php/find/{$table}", $criteria + ['limit' => $limit])
        ->throw()
        ->json();
}

Implementation Patterns

Pattern 1 — Profile as versioned artifact. The healthiest way to use this package is to keep profile.xml in your repo, treat it like a database migration, and let the bundle parse/diff it rather than hand-editing it in the Providence UI. If the bundle exposes a parser, the win is programmatic access to element codes (e.g. ca_objects.inscription_text) so your application code can reference stable constants instead of magic strings scattered across templates.

Pattern 2 — Metadata mapping layer. CollectiveAccess stores data in an attribute-value table keyed by element code and locale, not in columns. Any bundle worth its name will give you a way to flatten that into arrays. If it doesn't, write the mapper yourself and keep it in one class — you will be doing this regardless:

final class CaObjectMapper
{
    public function toArray(array $caItem): array
    {
        $attrs = collect($caItem['attributes'] ?? [])
            ->mapWithKeys(fn ($a) => [$a['element_code'] => $a['values'][0]['value'] ?? null]);

        return [
            'ca_id'      => $caItem['object_id'],
            'title'      => $attrs['ca_objects.preferred_labels'],
            'accession'  => $attrs['ca_objects.idno'],
            'inscription'=> $attrs['ca_objects.inscription_text'],
        ];
    }
}

Pattern 3 — Queue the sync, never inline it. Providence API calls are slow (CA is a heavyweight PHP app with a fat schema) and profile imports mutate schema. Put imports and bulk syncs behind a queued job with a lock, and make them idempotent by keying on ca_id / idno. An upsert on ca_objects.idno is the only safe re-run strategy.

Pattern 4 — Bidirectional sync is a trap; pick a system of record. Decide up front whether Laravel or CollectiveAccess owns the data. If CA owns curation (usual case for museums/archives), your Laravel app should be a read replica plus a narrow write path for specific element codes. If you attempt full round-trip sync, you will lose to locale handling, relationship tables, and CA's own "preferred label" logic.

Pattern 5 — Bridge the two frameworks over HTTP. If a Symfony team owns the CA integration and you own the Laravel app, do not composer require the bundle into Laravel. Have the Symfony service expose a thin JSON endpoint (or a queue) and consume it. This preserves the bundle's value while keeping your Laravel app free of symfony/* version collisions.

Gotchas and Tips

The framework mismatch is the primary risk. Symfony bundles routinely hard-depend on symfony/http-kernel event subscribers and symfony/dependency-injection compiler passes. Pulling one into Laravel drags in a parallel container and can collide with packages that constrain symfony/* transitively (notably symfony/console via long-running CLI tooling). Composer will not always surface this as an error — sometimes you just get two symfony/http-foundation versions and strange behavior at runtime. Run composer why symfony/http-kernel before and after if you insist.

Zero stars and zero dependents means zero incident history. There is no one to search for when it breaks, no Stack Overflow corpus, and no guarantee the maintainer's private fork matches the public tag. Pin the exact commit hash, vendor the source into your repo if you adopt it, and budget for owning it outright.

CollectiveAccess's PHP version floor is your real ceiling. CA 1.x historically targets PHP 7.2–7.4. If your Laravel app is on PHP 8.2+, the bundle's constraints (and CA itself, if you self-host it) may force you into an older PHP for at least one service. Plan for two runtimes, or plan to run CA in its own container and talk to it only over HTTP — which is another argument for skipping the bundle.

Profile imports are destructive and unrecoverable. Importing a profile into an existing Providence install can add element sets, alter UI layouts, and in some workflows drop and recreate tables. Always dump the CA database and snapshot the ca_* schema before any import, and test against a throwaway CA instance. There is no --dry-run you should trust.

Element codes are the API, and they are case- and locale-sensitive. ca_objects.inscription_text and ca_objects.Inscription_Text are different keys. Generate PHP constants from the parsed profile rather than typing them, and centralize locale fallback (en_US → default) in exactly one place.

Debugging path when the bundle silently fails: Symfony bundles usually swallow transport errors behind a logger. Check (a) the bundle's own log channel via config/packages/monolog.yaml, (b) the Providence application log at <ca>/app/log/, and (c) whether the CA user tied to your API key actually has access to the target tables — CA permissions are per-table and per-action, and a 403 will often surface as an empty array rather than an exception.

Extension points to reach for first: if the bundle defines an event (e.g. pre/post profile import) or a tagged service interface for element handlers, subscribe there rather than forking. In Symfony terms that means an EventSubscriberInterface or a CompilerPass in your own bundle; in a Laravel bridge, listen on your own HTTP wrapper's events.

Reality check before you commit. This package scores near-zero on every signal available. Evaluate it against the alternative — a direct Http:: client to service.php plus a SimpleXML profile parser — and be honest that the alternative is roughly a day of work, fully under your control, with no PHP-version entanglement. Adopt the bundle only if reading src/ reveals genuine logic (profile diffing, relationship resolution, locale normalization) that would take you meaningfully longer to reimplement.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
muka/shape-reader
tdt/json
refinery29/php-cs-fixer-config
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules
loco/loco
starfederation/datastar-php
yupmin/modern-phystrix
stephenjude/extended-artisan-commands
lumphp/laravel-macroable
lumphp/laravel-collections
lumphp/laravel-contracts
sermepa/sermepa
arkecosystem/fortify