Laravel Eloquent - Encrypting/Decrypt Data on call
eloquent, encryption, laravel, laravel-4
Solution
It doesn't really make sense to encrypt everything. For example, you never want to encrypt the primary key; that doesn't even make sense. Likewise you probably don't want to encrypt the date fields; you'll lose the ability to perform any sort of SQL query on them.
With that in mind, you can try something like this:
class BaseModel extends Eloquent {
protected $encrypt = [];
public function setAttribute($key, $value)
{
if (in_array($key, $this->encrypt))
{
$value = Crypt::encrypt($value);
}
return parent::setAttribute($key, $value);
}
public function getAttribute($key)
{
if (in_array($key, $this->encrypt))
{
return Crypt::decrypt($this->attributes[$key]);
}
return parent::getAttribute($key);
}
public function attributesToArray()
{
$attributes = parent::attributesToArray();
foreach ($attributes as $key => $value)
{
if (in_array($key, $this->encrypt))
{
$attributes[$key] = Crypt::decrypt($value);
}
}
return $attributes;
}
}
then have all you models extend this one, and set the `$encrypt` property to whatever columns you want encrypted for that particular model.
P.S. If you want to use Eloquent's accessor functionality, you'll have to play with this a bit more.
Problem
I can use `Crypt` to encrypt/decrypt my data. I want to encrypt some information in my db (such as the name, email, phone number to name a few). Assuming that I want EVERYTHING to be encrypted, I want to be able to do this in the background by itself, which I can perform by overwriting the `create` and `save` functions: ``` // For instance, the save() function could become public function save(array $options = array()) { foreach ($this->attributes as $key => $value) { if (isset($value)) $this->attributes[$key] = Crypt::encrypt($value); } return parent::save($options); } ``` Now, I want the decryption to be performed the same way, so that when I say `User::find($id)`, the returned `$user` is already decrypted. Also other functions such as `firstOrFail()` `get()` `first()` and all to work as well. I also would like this functionality to be extended when I use relationships (so `User::with('someOtherTable')->find($id)` also work). Would this be possible? If this is not possible, I am thinking of creating a helper function `decyrpt()` ``` function decrypt($array) { if (!is_array($array)) return Crypt::decrypt($array); $result = []; foreach($array as $key => $value) $result[$key] = decrypt($value); return $result; } ``` And pass all my results through this first, and then start using them, but it would be nicer if Laravel would provide this, or if there was a "Laravel Way" of doing this.