Silverstripe:将数据库值与cms字段进行转换

Silverstripe:将数据库值与cms字段进行转换,silverstripe,Silverstripe,我使用整数在数据库中存储钱。这意味着0.50美元等于50美元。我扩展了Integer db字段,使其在前端正常工作。它可以很好地转换为整数和整数 但在后端,我遇到了问题。silverstripe CMS似乎进行了自己的转换(例如添加了1000个分隔符),这有一个有趣的结果:) 你们怎么解决这个问题?我尝试使用onbeforewite和自定义getter 这是我的代码,从integer db字段的扩展开始 /** * Format a number to currency * @par

我使用整数在数据库中存储钱。这意味着0.50美元等于50美元。我扩展了Integer db字段,使其在前端正常工作。它可以很好地转换为整数和整数

但在后端,我遇到了问题。silverstripe CMS似乎进行了自己的转换(例如添加了1000个分隔符),这有一个有趣的结果:)

你们怎么解决这个问题?我尝试使用onbeforewite和自定义getter

这是我的代码,从integer db字段的扩展开始

    /**
 * Format a number to currency
 * @param int    $number_of_decimals    When larger than 0 it will return this number of decimals, AND divide the amount by 10^number of the amount of decimals
 * @param bool   $round                 Round the resulting number to the closest whole number
 * @param string $thousands_char        Character used as thousands separator
 * @param string $decimal_char          Character used as decimal separator
 * @return string
 */
public function toCurrency($number_of_decimals=2, $round=false, $thousands_char=".", $decimal_char=",") {
    $divide_by = pow(10,$number_of_decimals);
    $value = $this->owner->value/$divide_by;
    if($round) {
        //no decimals when rounding :)
        $number_of_decimals=0;
    }
    return number_format($value, $number_of_decimals, $decimal_char,$thousands_char);
}

public function fromCurrency($number_of_decimals=2, $thousands_char=".", $decimal_char=",") {
    $multiply_by = pow(10,$number_of_decimals);
    //get rid of the thousand separator
    $value = str_replace($thousands_char,"",$this->owner->value);
    //replace the decimal char with a point
    $value = str_replace($decimal_char,".",$value);
    $value = $value*$multiply_by;
    return number_format($value, 0, ".","");
}
我还将其添加到SiteConfig的扩展中(从而创建了一种全局可用的函数)

/**
 * Creates a DBField equivalent of the value, based on the type. In such a way, we can make use of the dame functions that are in an extension of a dbfield.
 * @param $type The type of the DBfield to create (e.g. Varchar, Int etc.).
 * @param $value The value, a string or number
 * @return mixed
 */
public function ToDBField($type,$value) {
    $field = $type::create();
    $field->setValue($value);
    return $field;
}
这些函数执行实际工作,它们位于dataobject中:

    public function GetAmount() {
        $amount = parent::getField("Amount");
        if (is_subclass_of(Controller::curr(), "LeftAndMain")) {
            $int_amount = SiteConfig::current_site_config()->ToDBField("Int", $amount);
            return $int_amount->toCurrency($number_of_decimals=2, $round=false, $thousands_char="", $decimal_char=".");
        }
        return $amount;
    }

    public function onBeforeWrite() {
        $int_amount = SiteConfig::current_site_config()->ToDBField("Int", $this->Amount);
        $this->Amount = $int_amount->fromCurrency(2,",",".");
        parent::onBeforeWrite();
    }

因此,您面临的问题是基于
DbField
类型的默认支架。默认情况下,type
Int
将在CMS中使用一个
NumericField
,它不进行货币格式化

我们可以在
DataObject
getCMSFields
函数中覆盖表单字段的支架。具体使用来用我们选择的一个替换表单字段

function getCMSFields()
{
    $fields = parent::getCMSFields();
    $fields->replaceField('Amount', CurrencyField::create('Amount', 'Amount'));

    return $fields;
}
您可以从零开始构建自己的表单字段、在现有表单字段的基础上构建表单字段或使用预先存在的表单字段。这两种方法都可以实现您想要的功能,而无需在
DataObject
上公开自己的函数来进行来回转换

有几件事需要注意:

  • 根据文档,
    CurrencyField
    仅限于以美国为中心的格式
  • CurrencyField
    MoneyField
    的设计不是以整数为后盾的
在这一点上,我会考虑改变你的方法。<代码> Munyfield 似乎描述了最接近你想要的更容易处理不同货币的能力。缺点是它需要一个数据库字段。

我从来没有使用过
MoneyField
,尽管我相信在一些项目中我使用过
CurrencyField
。正因为如此,我不能说它是多么容易操作和调整到您想要的方式


如果您仍然不想采用这种方法,我可能会考虑扩展
CurrencyField
类(我指的是面向对象的扩展类)根据您的喜好调整。然而,实现这一点可能太广泛了,在这个问题中无法涵盖。

我们可以看看您的DataObject是什么样子吗?我很好奇,为什么您要使用整型DB字段,而您可以使用一个字段。这加上从声音中对代码进行的一些其他调整,应该可以帮助您获得想要的工作ng.好的,基本上是因为精度和一些货币没有小数,而其他货币有小数。顺便说一下,我不知道货币字段。对于您的场景,扩展一个DBField(整数或货币)如何?扩展它应该可以让您更好地处理多个货币(因为如果不是这样,这两个领域都不是完美的结合)并可能扩展其中一个FormFields,以最好地呈现CMS中的自定义DBField。也就是说,您没有提到CMS当前使用的FormField元素,NumericField或CurrencyField?我们可以看到一些与您当前如何进行此设置相关的代码吗?我添加了一些代码。在CMS中,我只使用了一个脚手架可用于整数字段。也许我应该将其转换为varchar字段。首先我要提到的是您的SiteConfig扩展,它听起来像是您构建的/非常想使用的。对于您的应用程序,您希望在CMS中有一个数字字段来更改整数值,还是一个转换为整数的货币格式字符串?