Welcome Guest, Not a member yet? Register   Sign In
"Hidden" Fields for Models
#1

Supposing I have a database model representing a user. If I set up a REST controller for the User model, I don't want the password field to be returned when it is queried. Similarly, I don't want the password to be displayed in a HTML page if I need to use it in a template.
Although I'm pretty sure there's a way to do this using Entity classes (maybe by using smart getters?), I think this should be a built-in feature for Models.
Reply
#2

In the HTML template, you yourself determine which fields to display.

For an API, for example, you can use a wrapper class that will return a set of just the fields you need.
PHP Code:
class UserDecorator implements JsonSerializable
{
    protected 
Entity $entity;

    public function 
__construct(Entity $entity)
    {
        
$this->entity $entity;
    }

    protected function 
fields()
    {
        return [
            
'name',
            
'id',
        ];
    }

    public function 
jsonSerialize()
    {
        
$data = [];

        foreach (
$this->fields() as $field) {
            
$data[$field] = $this->entity->__get($field);
        }

        return 
$data;
    }
}
new 
UserDecorator((new Model)->find($id)); 

You can specify only the required fields when working with the model.
PHP Code:
(new Model)->select('name''id')->find($id); 
Or write your own logic for processing the result of the request and call it through model events.
Reply
#3

Very nice coverage from @iRedds. I would recommend this as a general practice regardless of sensitive fields. I rarely find my API resources to be 1:1 with their database counterparts. Sometimes Entity casts is enough to handle this but often I want more flexibility, like adding related entity names or aggregates, or removing redundant fields.
Reply
#4

(This post was last modified: 06-30-2022, 08:05 AM by b126.)

(06-14-2022, 08:56 AM)christianitis Wrote: Supposing I have a database model representing a user. If I set up a REST controller for the User model, I don't want the password field to be returned when it is queried. Similarly, I don't want the password to be displayed in a HTML page if I need to use it in a template.
Although I'm pretty sure there's a way to do this using Entity classes (maybe by using smart getters?), I think this should be a built-in feature for Models.

Personally, I am using JMS Serializer which makes it really easy to select the fields you want to expose or to exclude.
I do it thru simple annotations in my Doctrine entities.

In the following example, all the fields will be excluded but the ones with @Serializer\Expose()

PHP Code:
/**
* Product
*
* @ORM\Table(name="PRODUCT")
* @ORM\Entity
* @Serializer\ExclusionPolicy(policy="all")
*/
class Product
{
    /**
    * @var string
    *
    * @ORM\Column(name="CODE", type="string", length=10, nullable=false)
    * @Serializer\Expose()
    */
    private $code;

    /**
    * @var string
    *
    * @ORM\Column(name="DESCRIPTION", type="string", length=50, nullable=false)
    * @Serializer\Expose()
    */
    private $description;

    /**
    * @var string|null
    *
    * @ORM\Column(name="SECRETMARGIN", type="string", length=250, nullable=true)
    */
    private $secretMargin
Reply
#5

I agree with the philosophy of "create the data you want to return" instead of relying just on magic. So a custom function to get the API representation would be good.

You might look into the PHP League's Fractal. It helps solve a number of issues around this, especially when you data gets more complex.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB