Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the system of a filtration of parameters of model for restful is added #34

Closed
wants to merge 4 commits into from
Closed

Conversation

rez1dent3
Copy link

@rez1dent3 rez1dent3 commented Mar 24, 2017

Table users (id, login, passwordHash)

my model

class User extends UserLogin
{
    protected $hidden = ['passwordHash'];
}

return from processor.

return $orm->query('user')->findOne()->asObject(true);

result for resuful api

{
  "id": 1,
  "login": "rez1dent3"
}

without filter

return from processor.

return $orm->query('user')->findOne()->asObject(true, false);

result for resuful api

{
  "id": 1,
  "login": "rez1dent3",
  "passwordHash": "data"
}

ЗЫ, Аналог: https://laravel.com/docs/5.4/eloquent-serialization#hiding-attributes-from-json

@dracony
Copy link
Member

dracony commented Mar 24, 2017

Хм на самом деле это чуть лишнее:

  1. Логика того какие поля показывать пользователю не должна быть на уровне ОРМ, это уже контроллер рещает что он хочет отдавать а что нет.Я понимаю что это решение было сделано с мыслями о прятании passwordHash, но это достаточно единичный случай. В большинстве случаев тебе надо будет писать логику наоборот (какие поля показывать а не какие прятать)

  2. Для случая с passwordHash это можно решыть намного проще просто переопределив метод:

protected function asObject(...$params) //PHP 5.5+
{
     $object = parent::asObject(...$params);
     unset($object->passwordHash);
     return $object;
}
  1. В то ремя как наличие параметра $fields в find() гибко и позволяет в каждом запросе указывать свои параметры, у тебя параметр $filter строго булевой.

Словом я веду к тому что филтрировать поля надо уже на уровне презентации, или перегрузкой метода или созданием спецыального "getPublicObject" метода а не харкодом полей в сущности и переключении булевым флагом.

Словом я спрошу в чате что он думают, но мое имхо что сунуть это в апи ОРМ не особо надо.

@rez1dent3
Copy link
Author

rez1dent3 commented Mar 24, 2017

У меня много данных с которыми я работаю и которые мне не нужно отдавать на RESTful.
К примеру, зная структуру, многие могут сделать следущий запрос.

/api/post/1?preload[]=user.tokens

Конечно, я ограничиваю такие запросы. Но вероятность не уследить огромная. Лучше при создании модели и прописать hidden, как это сделано в laravel. Моделей в которых нужно скрывать данные много. И нет, не только из-за passwordHash, а еще и из-за email, login, phone ... Так сказать скрытие личной информации, если пользователь не разрешил отображение

@dracony
Copy link
Member

dracony commented Mar 24, 2017

Именно поэтому тебе надо сделать фильтр доступных полей, а не спратянных. Так гораздо понятнее, так как у тебя сразу есть список полей которые пользователь будет видеть. К тому же тогда шораздо труднее допустить ошыбку, добавив поле в базу но не добавиви его в список спрятанных.

К тому же логика спрятанноси может быть разная, например админ видит больше полей чем единствнный пользователь. В твоем случае достаточно просто перегоурзить asObject как я выше сделал.

@dorantor
Copy link

Согласен с @dracony - перегрузка метода, по сути, то же самое что и определение списка hidden, но с возможностью легко добавить дополнительную логику скрытия/раскрытия в нужный момент. А этот момент всегда наступает.
По мне, практичнее, сделать родительский класс, где переопределить asObject и научить его брать список полей которым нужен unset из $this->hidden.
Так ты малой кровью получаешь и гибкость, и то что тебе нужно и не добавляется логика(читай - тормоза) в фреймворк.
Как альтернативный вариант, можно покопать в сторону трэйта, но пока не вижу как его эффективно вкрутить. Так эта логика будет подключаться только тогда когда она нужна.

@dorantor
Copy link

@rez1dent3, будешь смеяться, но твои комменты в коде гораздо нужнее и ценнее :)

Кстати, filter - это как раз то, как можно реализовать трэйт. Назвать его, скажем, HiddenFieldsFilter и пусть он добавляет метод addFilter(или setFilter?) чтобы можно было добавить closure на свою логику фильтрации, а по дефолту пусть будет тупой ансет всего что перечислено в поле hidden. Плюс ему нужно переопределить метод asObject(согласно доке http://php.net/manual/en/language.oop5.traits.php, это должно сработать). Где будет просто последовательно вызываться родительский метод и closure определённая в addFilter. Если addFilter не вызывался объекту ни разу, то используется дефолтный метод фильтрации.

@rez1dent3 rez1dent3 closed this Jan 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants