Add or adjust functionality of installed packages

笑着哭i 提交于 2019-12-12 05:57:19

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!