1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-06-21 03:04:04 +00:00
Commit graph

108 commits

Author SHA1 Message Date
b3d11587ae
cast numeric params to string params 2026-06-08 15:32:45 -07:00
lukinovec
f9636b15cf Use Arr::wrap instead of (array) 2026-06-08 11:08:34 +02:00
lukinovec
9ea085ef05
Improve wording
Co-authored-by: Samuel Stancl <samuel@archte.ch>
2026-06-08 11:02:34 +02:00
lukinovec
4386a3b1a3 Improve annotations in ValidatesDatabaseParameters 2026-06-08 10:38:23 +02:00
lukinovec
6e82a9ee55 Change @mixin annotations to @see 2026-06-08 09:06:10 +02:00
9055b61a04
Merge branch 'master' into validate-sql-parameters 2026-06-07 14:17:28 -07:00
lukinovec
ad4c924d5c
[MINOR BC] Create pending tenants with pending_since, improve --with-pending (#1458)
> Minor breaking change: Pending tenants would previously go through the
creation pipeline as *not* pending and would only be marked as pending
after full creation. Now, pending tenants go through the creation
process with pending_since set from the start.

Pending tenants aren't getting their `pending_since` set until they're
created completely (e.g. their DB was created, migrated and seeded --
first, the tenant is created fully, and only after that, the tenant is
updated to have `pending_since`). This is a problem if someone wants to
e.g. add a job to the `DatabaseCreated` job pipeline that would check
`$this->tenant->pending()`. Since at the point of `DatabaseCreated`, the
tenant's `pending_since` isn't set yet, `$this->tenant->pending()`
returns `false`, even for tenants created using `createPending()`. So
instead of letting the pending tenant get fully created, and only after
that, setting its `pending_since` (using `update()`), we now set
`pending_since` in `create()`. `CreatingPendingTenant` is now dispatched
from the `static::creating` hook, and `PendingTenantCreated` is
dispatched from `static::created` for consistency.

Setting `pending_since` right in `create()` made the `MigrateDatabase`
and `SeedDatabase` jobs exclude the pending tenants during their
creation if the `tenancy.pending.include_in_queries` config was set to
`false` -- in that case, these jobs would never migrate or seed the
databases of pending tenants. So these jobs now pass `--with-pending` to
their underlying commands, with the value set in their `$includePending`
static property (`true` by default). This overrides the
`tenancy.pending.include_in_queries` config -- unless the
`$includePending` properties are set to `false`, these jobs will always
include pending tenants.

The `--with-pending` tenant command option originally worked just to
opt-in for including pending tenants in the command. Now,
`--with-pending` can accept values (`true`/`1` or `false`/`0`), so e.g.
- `tenants:run foo` with
`--with-pending`/`--with-pending=true`/`--with-pending=1` includes
pending tenants
- `tenants:run foo` with `--with-pending=false`/`--with-pending=0`
**excludes** pending tenants (also `--with-pending=foobar` -- invalid
input, considered `false`)

Passing `--with-pending` makes the command bypass the
`tenancy.pending.include_in_queries` config (so e.g. if
`tenancy.pending.include_in_queries` is set to `true`, and
`--with-pending=false` is passed to a command, the command will exclude
pending tenants). When `--with-pending` is not passed, the command will
include or exclude pending tenants based on the
`tenancy.pending.include_in_queries` config.

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2026-06-05 15:36:57 -07:00
41701aff5f
phpstan fix: Model covariants in Scope generics
Builds on changes in recent commit:
Commit ID: c32f52ce7c
Change ID: qsnosyvyulxzrnzorpxqwqqztmqorsmk
2026-05-01 16:09:52 +02:00
lukinovec
ea20eb13b6 Validate in-memory DBs outside of isInMemory
isInMemory should check if the name looks ilke an in-memory database name and return bool (it shouldn't throw validation errors).

Also, make the validation methods non-static.
2026-05-01 15:22:40 +02:00
lukinovec
429e0985fd Improve code quality and comments 2026-05-01 15:17:38 +02:00
lukinovec
48b4837905 Validate in-memory db names, move SQLite-specific methods to the SQLiteManager 2026-05-01 14:09:56 +02:00
github-actions[bot]
fc6a931a32 Fix code style (php-cs-fixer) 2026-05-01 09:50:30 +00:00
lukinovec
1a01164b87 Make validateFilename accept string instead of ?string 2026-05-01 10:46:37 +02:00
lukinovec
2bdda23a56 Disallow empty strings as filenames 2026-05-01 10:37:22 +02:00
github-actions[bot]
f3836cc623 Fix code style (php-cs-fixer) 2026-05-01 07:34:32 +00:00
lukinovec
9611a05f35 Skip null parameters, throw for other non-string parameters 2026-05-01 09:34:11 +02:00
lukinovec
e8168eb0b9 Add string check to validateFilename, swap validation order
Validate characters first, only then throw if the filename is a directory.
2026-05-01 09:16:17 +02:00
lukinovec
d3607f84bf Use 'allowedCharacters' instead of 'allowlist', code quality 2026-05-01 09:11:55 +02:00
lukinovec
76c324d758 Add validateFilename()
Use validateFilename instead of validateParameter in SQLiteDatabaseManager. Directories are no longer considered valid SQLite database names.
2026-05-01 09:03:50 +02:00
lukinovec
37a4c7dd27 Check if paremeter is string 2026-04-30 15:08:46 +02:00
lukinovec
bacbf934e1 Improve validation exception message 2026-04-30 14:52:53 +02:00
lukinovec
46f73c42ad Improve ValidatesDatabaseParameters comments, delete extra early return 2026-04-30 10:44:36 +02:00
lukinovec
75b74f2e6c Make validateParameter have void return type 2026-04-30 09:28:48 +02:00
lukinovec
f3f1ab977a
Skip null parameters in validateParameter
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-04-30 09:15:18 +02:00
lukinovec
85929493d5 Improve ValidatesDatabaseParameters docblocks 2026-04-29 17:35:11 +02:00
lukinovec
740d53e9cc Rename ValidatesSqlParameters to ValidatesDatabaseParameters 2026-04-29 17:35:11 +02:00
lukinovec
0fdb8b2041 Validate user passwords in DB managers
Also, make the validateParameter method ignore null parameters, e.g. for cases when tenants are created using Tenant::make() without tenancy_db_username set -- $databaseConfig->getUsername() allows null, same should go for the validate method whose only concern is checking strings for invalid characters.
2026-04-29 17:35:11 +02:00
lukinovec
d5087d19c5 Extract parameter validation into a trait
Also, use parameterAllowlist() instead of the static property (so that we can e.g. override it later in SQLiteDatabaseManager, since overriding the static property doesn't work).
2026-04-29 17:35:11 +02:00
github-actions[bot]
182f3a2eb2 Fix code style (php-cs-fixer) 2026-04-29 12:16:22 +00:00
lukinovec
bdf592c0ff Add parameter validation to DB managers
DB manager methods validate the parameters they use in SQL statements using validateParameter() (excluding parameters passed via bindings in SELECT statements).
2026-04-29 14:13:56 +02:00
lukinovec
ad7d229daf Use parameter binding in SELECT queries 2026-04-29 10:21:47 +02:00
lukinovec
808f52765c Use select() instead of selectOne() in databaseExists() and userExists()
This is just for consistency, since all the other DB managers use select().
2026-04-29 10:08:45 +02:00
lukinovec
ab2a4d8438
Fix chaining withoutPending() with where() (#1457)
At the moment, `where()` cannot be used correctly while using
`withoutPending()`. For example, if we have a single non-pending tenant
in our DB (with ID 'foo'), queries like
`Tenant::withoutPending()->where('id', 'nonexistent')->first()`will
incorrectly return the non-pending tenant ('foo').

This is because `withoutPending()` does
`$builder->whereNull('data->pending_since')->orWhereNull('data')`. These
two aren't grouped, so `withoutPending()->where('id', 'nonexistent')`
basically translates to "WHERE data->pending_since IS NULL **OR (data IS
NULL AND id = 'nonexistent')**". So the query will include all tenants
whose `pending_since` is null (= all non-pending tenants).

Grouping `->whereNull('data->pending_since')->orWhereNull('data')` in a
closure passed to a separate `where()` fixes this issue.
2026-04-22 14:32:53 +02:00
c32f52ce7c
phpstan fix: Scope generics
phpstan started failing with '... implements generic interface
Illuminate\Database\Eloquent\Scope but does not specify its types:
TModel'. We solve this by adding an implements docblock to the scopes
implementing that interface. They're fairly generic - we just use the
Model type itself in the code - so we use Model for the type parameter.
2026-04-15 11:23:12 +02:00
c4960b76cb
[4.x] Laravel 13 support (#1443)
- Update ci.yml and composer.json
- Wrap single database tenancy trait scopes in whenBooted()
- Update SessionSeparationTest to use laravel-cache- prefix in L13
  and laravel_cache_ in <=L12. Our own prefix remains tenant_%tenant%_
  (as configured in tenancy.cache.prefix). We could update this to be
  tenant-%tenant%- from now on for consistency with Laravel's prefixes
  (changed in https://github.com/laravel/framework/pull/56172) but I'm
  not sure yet. _ seems to read a bit better but perhaps consistency
  is more important. We may change this later and it can be adjusted
  in userland easily (since it's just a config option).
2026-03-18 19:17:28 +01:00
Punyapal Shah
e3701f1cc1
[4.x] Add more relation type annotations (#1424)
This pull request adds improved PHPDoc type annotations to several
Eloquent relationship methods, enhancing static analysis and developer
experience. These changes clarify the expected return types for
relationships, making the codebase easier to understand and work with.

Relationship method type annotations:

* Added a detailed return type annotation to the `tenant` method in the
`BelongsToTenant` trait, specifying the related model and the current
class.
* Added a detailed return type annotation to the `domains` method in the
`HasDomains` trait, specifying the related model and the current class.
* Added a detailed return type annotation to the `tenants` method in the
`ResourceSyncing` class, specifying the related model and the current
class.
2025-12-28 23:20:05 +01:00
d274d8c902
pending tenants: minor cleanup 2025-10-29 22:54:53 +01:00
6523f24a60 Pending tenants: Add getPendingAttributes()
This method lets the user specify default values for custom
non-nullable columns. The primary use case is when the tenants table
has a column like 'slug' and createPending() is called with no
value for 'slug'. This would produce an exception due to the column
having no default value.

Here, getPendingAttributes() can set an initial dummy slug (like a
randomly generated string) before it's overwritten during a pull.

getPendingAttributes() accepts an $attributes array which corresponds
to the attributes passed to createPending(). The array returned from
getPendingAttributes() is ultimately merged with $attributes, so
the user doesn't need to use the $attributes value in
getPendingAttributes(), however it serves to provide more context when
the pending attributes might be dependent on $attributes and therefore
derived from the $attributes actually being used.

Also fixed the `finally` branch in createPending() as it was
potentially referencing the $tenant variable before it was initialized.
2025-10-28 12:50:13 +01:00
a0a9b85982 Refactor DatabaseConfig, minor DB manager improvements, resolve todos
Notable changes:
- CreateUserWithRLSPolicies: Clarify why we're creating a custom
  DatabaseConfing instance
- HasDatabase: Clarify why we're ignoring tenancy_db_connection
- DatabaseConfig: General refactor, clarify the role of the host conn
- SQLiteDatabaseManager: Handle trailing DIRECTORY_SEPARATOR
  in static::$path
- DisallowSqliteAttach: Don't throw any exceptions, just silently fail
  since the class isn't 100% portable
- Clean up todos that are no longer relevant
- Clean up dead code or comments in some database managers
2025-10-13 16:01:34 +02:00
6b0066c5ef Pending tenants refactor (BC break)
- [BC BREAK] Make pullPendingFromPool() $firstOrCreate arg
  default to false (pullPending() is now a direct alias for
  pullPendingFromPool() with default $firstOrCreate=true)
- Resolve race conditions in pullPendingFromPool()
- Make createPending() set pending_since regardless of exceptions
- Make pullPending() accept $attributes
- Fire PullingPendingTenant from within a DB transaction
- Clarify --count arg description for CreatePendingTenants command
- Add docblock to PullingPendingTenant with a notice
2025-08-25 00:01:02 +02:00
f4cc99b317 fix phpstan 2025-05-29 18:39:05 +02:00
37a0f1a713
[4.x] Invalidate resolver cache on delete (#1329)
* Invalidate resolver cache on delete

* Fix code style (php-cs-fixer)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-13 17:03:49 +01:00
657e165cc8
[4.x] Cleanup (#1317)
* cleanup, resolve todos, add immediate todos

* Improve path_identification_middleware docblock

* rename leave() method in tests

* wip fix hardcoded values making assumptions about the parameters used in routing

* defaultParameterNames

* fix CreatesDatabaseUsers return values

* $tenant -> tenant()

* resolve more todos

* make comment block a complete block

* Correct useTenantRoutesInFortify(), delete unused import

* test fixes

* remove todos

* remove JobPipeline todo

* simplify comment example

* remove todo

* fix VERSION_PREFIX in queue.yml

---------

Co-authored-by: lukinovec <lukinovec@gmail.com>
2025-02-20 20:49:09 +01:00
f955b38e2b phpstan fixes 2025-01-05 15:50:30 +01:00
Samuel Štancl
85bdbd57f7
Fix pullFromPendingPool() behavior (#70) 2024-11-25 04:44:39 +01:00
0fc105487b Tenant DB manager database() -> connection() 2024-09-12 18:34:45 +02:00
lukinovec
6b74589d76
Update specific attributes of pending tenants while they're being pulled (#59)
* Add option to update attributes of pending tenants while pulling them

* Fix failing toEqualCanonicalizing tests

* Fix code style (php-cs-fixer)

* fix code errors

* lock phpcsfixer to 3.62.0 due to a bug in 3.63.1

---------

Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2024-08-28 00:41:16 +02:00
4372e1bef2 fix phpstan errors 2024-08-06 04:35:25 +02:00
6b6c883234 phpstan fixes 2024-07-04 20:48:55 +02:00
7572911d87 remove dead code 2024-05-28 02:55:13 +02:00