将数据库字段类型从文本重载到 SS_DateTime

overloading DB field type from Text to SS_DateTime

我目前正在使用 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 的扩展,但是这个扩展也被其他对象上的其他字段共享,所以我可以't/shouldn'(?) 在 DBType 级别执行此操作。

由于这是在现有站点上,我宁愿不必重写此字段的所有提及以从字符串创建新的 SS_DateTime

如何在解密后将字段时间 "back" 重载到 DateTime

谢谢

根据 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'));
}

看来答案比我想象的要简单。简单地向对象添加转换似乎就可以完成这项工作。例如:

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

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