For anybody who comes across this thread, here is what I ended up doing. In the end, requiring the team to be identified in the URI was the only real choice and I've built a convention now that at least works for me.
My TeamScope looks like this now:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class TeamScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$team = request()->route('team');
$builder->where(
'team_id', '=', $team->id
);
}
}
So I'm now grabbing the team directly from the request (if you're not using Spark, you'll also need to set up explicit route model binding to resolve team from the URL)
My original concern with this method was now how do I tweak all the routes so the URI has the {team_id} in it without completely duplicating my frameworks route list. For this, I ended being more explicit about my route registration in the framework service provider:
<?php
namespace TechnicPack\SolderFramework;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
class SolderFrameworkServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*/
public function boot()
{
// Register framework resources
$this->registerRoutes();
}
/**
* Register Solder's routes.
*/
private function registerRoutes()
{
// If the routes have not been cached, we will include them in a route group
// so that all of the routes will be conveniently registered to the given
// controller namespace. After that we will load the Solder routes file.
if (! $this->app->routesAreCached()) {
Route::name('api.')
->namespace('TechnicPack\SolderFramework\Http\Controllers')
->prefix(Solder::$apiRoutePrefix)
->group(function ($router) {
require __DIR__.'/Http/routes.php';
});
}
}
}
The key thing here is that the prefix call points to a static class which contains a default prefix of '/api' but can easily be overridden (you could do this with a config parameter too if you wanted).
<?php
namespace TechnicPack\SolderFramework;
class Solder
{
/**
* The string prefix for all solder api routes.
*
* @var string
*/
public static $apiRoutePrefix = 'api';
/**
* Set the uri to prefix api routes with.
*
* @param $prefix
*
* @return Solder
*/
public static function prefixApiRoutesWith($prefix)
{
self::$apiRoutePrefix = $prefix;
return new static();
}
}
Now, in my Spark application service provider I can override the prefix for all of my framework routes and inject the {team} into the URI:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use TechnicPack\SolderFramework\Solder;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register()
{
Solder::prefixApiRoutesWith('{team}/api');
}
}