Accessor, который расшифровывает значение модели, не работает - PullRequest
4 голосов
/ 26 января 2020

У меня есть черта, которая использует методы доступа и мутаторы для шифрования значений модели:

trait Encryptable
{
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);

        if (in_array($key, $this->encryptable)) {
            $value = Crypt::decrypt($value);
            return $value;
        } else {
            return $value;
        }
    }

    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable)) {
            $value = Crypt::encrypt($value);
        }

        return parent::setAttribute($key, $value);
    }
} 

Комментарии Модель

protected $fillable = ['content','user_id','commentable_id', 'commentable_type'];
protected $encryptable = [
    'content'
];

CommentController

public function storePostComment(Request $request, Post $Post)
{
    $this->validate($request, [
        'content' => 'required',
    ]);

    $comment = $post->comments()->create([
        'user_id' => auth()->user()->id,
        'content' => $request->content
    ]);


    dd($comment->content);
    //return new CommentResource($comment);
}

То, что происходит, когда я передаю return new CommentResource($comment);, дает мне зашифрованное содержимое комментариев, но dd($comment->content); дешифрует содержимое комментариев. Как мне расшифровать весь объект комментария, чтобы я мог вывести его на ресурс?

Редактировать для CommentResource

class CommentResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'content' => $this->content,
            'owner' => $this->owner,
        ];
    }
} 

Редактировать 2 для ответа

Вот моя попытка:

use App\Comment;

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class CommentResource extends JsonResource
{

    public function __construct(Comment $resource)
    {
        $this->resource = $resource;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'content' => $this->content,
            'owner' => $this->owner,
        ];
    }
}

Ошибка:

Аргумент 1 передан в App \ Http \ Resources \ CommentResource :: __ construct () должен быть экземпляр App \ Http \ Resources \ Comment, данный экземпляр App \ Comment, указанный в /Applications/MAMP/htdocs/my-app/app/Http/Controllers/Api/CommentController.php в строке 31

Редактировать 3 (окончательное редактирование)

Вот что я понял:

Я попробовал несколько различных комбинаций вместе с ответом @Edwin Krause. У меня есть другая модель, использующая эту зашифрованную черту и выводящую в ресурс, который работает отлично.

Чтобы немного больше понять этот вопрос, я обнаружил, что в тесте была проблема с использованием assertJsonFragment:

CommentsTest

/* @test **/
public function a_user_can_comment_on_a_post()
{
    $decryptedComment = ['content'=>'A new content']
    $response = $this->json('POST',  '/api/comment/' . $post->id, $decryptedComment);

        $response->assertStatus(201);

        $response->assertJsonStructure([
            'data' => [
                'owner',
                'content'
            ]
        ])
        ->assertJsonFragment(['content' => $decryptedContent['content']]);
}

assertJsonFragment возвращал зашифрованный контент и, следовательно, отказывал, потому что он проверялся на предмет содержимого с расшифрованными комментариями.

Я использовал dd(new CommentResource($comment)); в контроллере, чтобы проверить, расшифровывает ли его содержимое, это не было т.

Я пробовал разные способы устранения неполадок с dd() в методе контроллера и даже тестирование в браузере. Еще ничего. Я добавил код @Edwin Krause и все еще ничего на dd()

Мне наконец повезло, и я избавился от dd () с @Edwin Krause и изменил свой контроллер на:

Работа код в сочетании с ответом @Edwin Krause в моем CommentResource

$comment = Comment::create([
    'user_id' => auth()->user()->id,
    'content' => $request->content,
    'commentable_type' => 'App\Post',
    'commentable_id' => $post->id,
]);

return new CommentResource($comment);

Тесты прошли успешно. Я попытался dd(new CommentResource($comment));, и содержимое все еще было зашифровано. Вывод контента на браузер и assertJsonFragment работал. Должно быть, я попробовал так много комбинаций, чтобы понять это, и мне просто повезло.

Я не уверен, почему это так, но я уже потратил на это часы, поэтому не могу понять, почему он ломается. Может быть, кто-то еще может.

1 Ответ

1 голос
/ 26 января 2020

Просто предложение попробовать переопределить конструктор JsonResource и типизировать параметр $ resource в свой Modelclass. Это работает для других вещей, не уверен, если это решит вашу проблему, которая должна быть проверена на самом деле работа. У меня нет зашифрованных данных для игры, но по логике это должно работать.

...