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

Users Table Laravel Package

baks-dev/users-table

BaksDev UsersTable is a user timekeeping and attendance module for PHP 8.4+ projects. Install via Composer, publish assets, and apply Doctrine migrations to get started. Test with PHPUnit using the users-table group. MIT licensed.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate expectations. Despite living on Packagist and being installable with composer require, baks-dev/users-table is not a Laravel package. The README's own commands give it away: php bin/console baks:assets:install is Symfony Console, not php artisan, and doctrine:migrations:diff / doctrine:migrations:migrate are Doctrine Migrations, not Laravel's migrator. There is no service provider, no facade, no config/users-table.php to publish, and no Eloquent model. It is a Symfony bundle from the BaksDev ecosystem that models a табель учёта рабочего времени (employee timesheet / attendance ledger).

So as a Laravel developer, "getting started" really means deciding how you'll consume it. Three realistic paths:

  1. Read it, don't install it (recommended for most Laravel apps). The package is a schema + domain model reference. Clone it, read the Doctrine entities and migrations in vendor/baks-dev/users-table/, and re-implement the timesheet schema as a Laravel migration + Eloquent model. You get the design without the integration tax.
  2. DBAL-only integration. Install it, run its Doctrine migrations against your database, and point plain Eloquent models at the resulting tables. You use the schema, not the bundle code.
  3. Standalone Symfony service. Run it in a Symfony app next to your Laravel app, share the database or expose an HTTP boundary. Only worth it if you already run BaksDev bundles elsewhere.

Minimal steps (per the README, translated):

composer require baks-dev/users-table
# then, in a Symfony console context:
php bin/console baks:assets:install
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate

Where to look first, in this order:

  • composer.json — see the require block. This tells you the Symfony version band, the Doctrine ORM version, and which sibling baks-dev/* bundles are mandatory (the baks:assets:install command comes from one of them, not from this package).
  • src/Entity/ (or src/Domain/) — the Doctrine mappings. This is your real documentation. Look for the timesheet/attendance entity, its relation to a user identifier, and the value objects for dates/statuses.
  • migrations/ — the actual DDL. Read this before running anything.
  • Tests/ — the --group=users-table suite is your only executable spec.

First use case: an employee's daily timesheet row — user identifier, date, planned/actual hours, and an absence/status code. That's the unit everything else is built around. Get that table migrated and querying before you think about reporting.

Implementation Patterns

Schema ownership. Let the package (or a copy of its migrations) own the timesheet tables. Do not hand-roll a parallel attendance table in Laravel migrations and then also run the Doctrine migrations — you'll end up with two sources of truth and a broken diff on every deploy. Pick one owner per table.

Eloquent-over-Doctrine-schema (the pragmatic Laravel pattern). After migrating, define a read/write Eloquent model against the generated table:

class TimesheetEntry extends Model
{
    protected $table = 'users_table'; // confirm the real name in the migration
    protected $guarded = [];
    public $timestamps = false; // Doctrine tables rarely have Laravel's created_at/updated_at
}

Keep the package's column names exactly as-is. Renaming columns is where every "why doesn't it work" story starts.

User linkage. The bundle was built against the BaksDev user stack, so its user foreign key likely points at a users-style identifier that may not be your App\Models\User id. Map explicitly:

// Resolve your auth user to the package's identifier once, in a small service.
final class TimesheetUserResolver
{
    public function idFor(Authenticatable $user): string
    {
        return $user->timesheet_id ?? (string) $user->getKey();
    }
}

Never scatter auth()->id() through timesheet queries.

Query objects, not package APIs. The package exposes no documented public API (see Gotchas). Don't build controllers on guessed static facade calls. Write small query classes against the tables:

final class MonthlyHoursForUser
{
    public function __invoke(int $userId, CarbonImmutable $month): Collection
    {
        return TimesheetEntry::query()
            ->where('user_id', $userId)
            ->whereBetween('date', [$month->startOfMonth(), $month->endOfMonth()])
            ->get();
    }
}

Migrations workflow. If you keep Doctrine as the owner, treat doctrine:migrations:diff output as a pull request, not as a command to run. Diff, read, commit the generated migration, then migrate. In a Laravel app, run these via a separate console entry point or container command — not php artisan.

Events and hooks. If you need "notify on absence" or "increment absence counters," attach them to your domain, not to the bundle. Wrap writes in a Laravel service that fires your own events:

final class RecordTimesheetEntry
{
    public function __construct(private Dispatcher $events) {}

    public function handle(array $attributes): TimesheetEntry
    {
        $entry = TimesheetEntry::create($attributes);
        $this->events->dispatch(new TimesheetEntryRecorded($entry));
        return $entry;
    }
}

If you're genuinely in Symfony, use the bundle's service definitions in Resources/config/services.yaml and decorate its repositories; that's the supported extension mechanism.

Testing. You can piggyback on the package's own group if you're inside a Symfony test runner:

php bin/phpunit --group=users-table

For a Laravel app, ignore that and write feature tests around your Eloquent models and query objects. The package's tests validate its behavior, not your integration.

Gotchas and Tips

It is not a Laravel package. This is the single biggest gotcha and the reason you should not composer require it reflexively into a Laravel app and expect anything to appear. No service provider, no facade, no publishable config, no artisan command, no Blade views. If a previous assessment in your repo mentions UsersTable::recordAttendance(...) or php artisan vendor:publish --provider="BaksDev\UsersTable\UsersTableServiceProvider", that API is invented — it does not exist in this repository.

Two ORMs, one database. Mixing Doctrine ORM and Eloquent on the same tables works, but only if you respect each one's expectations: Doctrine wants its doctrine_entity conventions, Eloquent wants created_at/updated_at. Disable timestamps on Eloquent models over Doctrine-owned tables, and never let both write schema.

doctrine:migrations:diff is a whole-schema diff. In an app with existing Doctrine entities it will generate migration changes for everything, not just this package. Run it in a clean context, or inspect and prune the output before migrate. Running it blindly on a shared database is how you delete a column you cared about.

baks:assets:install depends on a sibling bundle. That command is provided by the BaksDev assets infrastructure, not by users-table. If the command is "not defined," the transitive dependency is missing or its config is unpublished — this is a dependency-chain problem, not a bug in this package.

PHP 8.4+ is a hard floor. The badge says min 8.4. If your Laravel app is on 8.2 or 8.3 (or you're pinned there by a hosting provider), composer require will fail or the code will error on new syntax. Check before you plan anything around it.

Zero stars, zero dependents, empty release notes. v7.4.3's changelog is the literal string "v7.4.3". There is no community, no issue history to search, no Stack Overflow answers. Your documentation is the source code. Budget time accordingly, or treat the repo as a design reference only (see Getting Started path 1).

Pin the version and vendor-check it. With no adoption and no changelog discipline, treat any version bump as a review-required change: read the diff of the migration directory before upgrading. Better still, if you're only borrowing the schema, copy the migrations into your own repo and own them — that removes the upgrade problem entirely.

Debugging checklist when something silently doesn't work:

# Is the schema what Doctrine thinks it is?
php bin/console doctrine:schema:validate

# What migrations exist and which ran?
php bin/console doctrine:migrations:status

# What's actually registered from this bundle?
php bin/console debug:container | grep -i users.table

In a Laravel app, the equivalents are php artisan migrate:status for your own migrations and plain SQL against information_schema for the Doctrine tables.

The real extension points are Doctrine entity overrides (via bundle config / attribute mapping overrides), service decoration in services.yaml, and — the honest answer — a fork. The MIT license makes forking trivial and it's the realistic path for anything beyond a pure schema lift.

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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin