将DB字段类型从Text重载到SS_DateTime

时间:2017-06-14 15:05:14

标签: php silverstripe

我目前正致力于使用defuse/php-encryption加密某些数据库字段。我选择这样做的方法是加密MyObject->setField()上的特定字段并在MyObject->getField上解密,如下所示:

public function getField($field)
{
    $val = parent::getField($field);

    if (in_array($field, static::$fieldsToEncrypt)) {
        $key = $this->getEncryptionKey();
        try {
            $newVal = Crypto::decrypt($val, $key);
            $val = $newVal;
        } catch (Exception $e) {
        }
    }

    return $val;
}

public function setField($fieldName, $val)
{
    if (in_array($fieldName, static::$fieldsToEncrypt)) {
        $key = $this->getEncryptionKey();
        $val = Crypto::encrypt($val, $key);
    }

    return parent::setField($fieldName, $val);
}

为了使加密工作,我必须将我的字段类型更改为Text,这对所有Varchar字段都适用。现在我有一个时间DateTime的字段也需要加密,好吧,它实际上是SS_DateTime的扩展,但是这个扩展也被其他对象的其他字段共享所以我不能/不应该(?)在DBType级别执行。

由于这是在现有网站上,因此我不必重写每个提及此字段的内容,以便从字符串中创建新的SS_DateTime

如何在解密后将字段时间“重新”重载到DateTime

谢谢

2 个答案:

答案 0 :(得分:2)

似乎答案比我预期的要简单。简单地向对象添加铸件似乎可以完成这项工作。例如:

private static $db = array(
    'DOB' => 'Text' // should be DateTime
);

private static $casting = array(
    'DOB' => 'DateTime'
);

答案 1 :(得分:0)

根据Silverstripe的文档https://docs.silverstripe.org/en/3/developer_guides/model/data_types_and_casting/#casting

,使用DBField::create_field()投射您的输出

示例:

private static $db = array(
    'Date' => 'Text' // Encrypted value
);

public function getField($field)
{
    $val = parent::getField($field);

    if (in_array($field, static::$fieldsToEncrypt)) {
        $key = $this->getEncryptionKey();
        try {
            $newVal = Crypto::decrypt($val, $key);
            $val = $newVal;
        } catch (Exception $e) {
        }
    }

    return $val;
}

public function getDate()
{
    // Cast it to DateTime
    return DBField::create_field('DateTime', $this->getField('Date'));
}