问题
I was wondering what the best practice would be to add or adjust some functionality to installed packages. I think extending the existing classes sounded like a good idea when I started this, but what seemed to be a small addition seems to result in many additions. Would this be the right way to go, and what's the next step?
E.g. I am using the Laravel/Passport package. Without going too much into detail on the why, a user with a client can send an e-mail to invite an other user. This user can accept the invite when he or she is logged in. For this I created following migration.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateInvitationRequestsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('oauth_invitation_requests', function (Blueprint $table) {
$table->increments('id');
$table->integer('client_id')->index();
$table->string('name');
$table->string('email');
$table->boolean('accepted');
$table->boolean('declined');
$table->boolean('revoked');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('oauth_invitation_requests');
}
}
And following model
<?php
namespace App;
use Laravel\Passport\Client;
use Illuminate\Database\Eloquent\Model;
class InvitationRequest extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'oauth_invitation_requests';
/**
* The guarded attributes on the model.
*
* @var array
*/
protected $guarded = [];
/**
* Get all of the invitation requests for the client.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function client()
{
return $this->belongsTo(Client::class);
}
}
When looking into the code of \Laravel\Passport\ClientRepository I notice the following piece of code
<?php
namespace Laravel\Passport;
class ClientRepository
{
...
/**
* Delete the given client.
*
* @param \Laravel\Passport\Client $client
* @return void
*/
public function delete(Client $client)
{
$client->tokens()->update(['revoked' => true]);
$client->forceFill(['revoked' => true])->save();
}
}
So when a client is deleted, all tokens are revoked as well. The same should happen to the related invitation requests. So I added following two classes
<?php
namespace App;
use Laravel\Passport\Client;
use Illuminate\Database\Eloquent\Model;
class PassportClient extends Client
{
/**
* Get all of the invitation requests from the client.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function invitationRequests()
{
return $this->hasMany(InvitationRequest::class, 'client_id');
}
}
and
<?php
namespace App;
use App\PassportClient;
use Laravel\Passport\ClientRepository;
class PassportClientRepository extends ClientRepository
{
/**
* Delete the given client.
*
* @param App\Client $client
* @return void
*/
public function delete(PassportClient $client)
{
$client->invitationRequests()->update(['revoked' => true]);
parent::delete($client);
}
}
I think I will have to need this one as well
<?php
namespace App\Http\Controllers;
use App\PassportClientRepository;
use Laravel\Passport\Http\Controllers\ClientController;
class PassportClientController extends ClientController
{
/**
* Create a client controller instance.
*
* @param \Laravel\Passport\ClientRepository $clients
* @param \Illuminate\Contracts\Validation\Factory $validation
* @return void
*/
public function __construct(PassportClientRepository $clients,
ValidationFactory $validation)
{
$this->clients = $clients;
$this->validation = $validation;
}
}
So far so good, I would think? But now I am kinda stuck. According to the documentation I had to add Passport::routes(); in the AuthServiceProvider, which loads the routes. I assume I have to overwrite the behavior for only one route and that would be the following one.
+--------+----------+-----------------------------------------+------------------+----------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-----------------------------------------+------------------+----------------------------------------------------------------------------+--------------+
| | DELETE | oauth/clients/{client_id} | | \Laravel\Passport\Http\Controllers\ClientController@destroy | web,auth |
+--------+----------+-----------------------------------------+------------------+----------------------------------------------------------------------------+--------------+
I am a bit confused on how Laravel loads the routes exactly, and am not sure what class I should inherit further to make this work.
来源:https://stackoverflow.com/questions/45147106/add-or-adjust-functionality-of-installed-packages