无法设置日期时间字段 CakePHP 3
Unable to set date time field CakePHP 3
我有一个突变体:
protected function _setPurchaseTime($purchase_time) {
return Time($purchase_time);
}
当我像这样设置值时,这个增变器变得 运行 正常:
$transaction->purchase_time = $this->request->data['purchase_time'];
增变器正确获得 $purchase_time
。但是当我尝试这样设置时:
$transaction = $this->Transactions->patchEntity($transaction, $this->request->data);
$purchase_time
为空。我不明白为什么会这样?增变器得到 运行 就好了,但是变量是空的。
编辑:
我还应该补充一点,purchase_time
是可以访问的:
protected $_accessible = [
'ticker' => TRUE,
'name' => TRUE,
'market' => TRUE,
'transaction_type' => TRUE,
'price' => TRUE,
'currency' => TRUE,
'commission' => TRUE,
'shares' => TRUE,
'purchase_time' => TRUE
];
编辑:添加了额外的数据
这是进入 patchEntity 的数据:
[
'ticker_label' => 'AAPL (Apple Inc.)',
'ticker' => 'AAPL',
'currency' => 'USD',
'market' => 'NASDAQ',
'transaction_type' => 'Buy',
'price' => '10',
'commission' => '10',
'shares' => '10',
'date' => 'Yesterday',
'purchase_time' => 'July 12, 2015 12:00',
'time' => '12:00',
'name' => 'Apple Inc.'
]
这是patchEntity之后的数据是运行:
object(App\Model\Entity\Transaction) {
'portfolio_id' => '43',
'ticker' => 'AAPL',
'currency' => 'USD',
'market' => 'NASDAQ',
'transaction_type' => 'Buy',
'price' => (float) 10,
'commission' => (float) 10,
'shares' => (float) 10,
'purchase_time' => (int) 1436803512,
'name' => 'Apple Inc.',
'[new]' => true,
'[accessible]' => [
'ticker' => true,
'name' => true,
'market' => true,
'transaction_type' => true,
'price' => true,
'currency' => true,
'commission' => true,
'shares' => true,
'purchase_time' => true
],
'[dirty]' => [
'portfolio_id' => true,
'ticker' => true,
'currency' => true,
'market' => true,
'transaction_type' => true,
'price' => true,
'commission' => true,
'shares' => true,
'purchase_time' => true,
'name' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Transactions'
}
可以看到,如果对purchase_time
字段中的Unix时间戳进行转换,则不等于输入。它现在等于当前时间,这在将 NULL
值传递给 Time()
.
时是预期的
问题是 CakePHP 中的 DatetimeType
class 需要规范化格式的输入。作为数组(表单输入)或 ISO 格式的字符串。
由于您以本地化格式提供输入,因此您需要 enable the locale parser、以 ISO 格式发送输入、在将数据转换为日期时间之前对其进行转换,或者扩展 DateTimeType
class 以满足您的需求。
一个简单的方法是使用 Model.beforeMarshal
事件:
$table->eventManager()->on('Model.beforeMarshal', function ($event, $data) {
if (!empty($data['the_time_field']) {
$data['the_time_field'] = new Time($data['the_time_field'])
}
});
重要的是要记住,如果无法正确验证数据或者无法在类型 classes 的帮助下由编组器 "parsed" 将数据设置到实体,这一点很重要。这就是使用 patchEntity 时未调用 setter 的原因。
我有一个突变体:
protected function _setPurchaseTime($purchase_time) {
return Time($purchase_time);
}
当我像这样设置值时,这个增变器变得 运行 正常:
$transaction->purchase_time = $this->request->data['purchase_time'];
增变器正确获得 $purchase_time
。但是当我尝试这样设置时:
$transaction = $this->Transactions->patchEntity($transaction, $this->request->data);
$purchase_time
为空。我不明白为什么会这样?增变器得到 运行 就好了,但是变量是空的。
编辑:
我还应该补充一点,purchase_time
是可以访问的:
protected $_accessible = [
'ticker' => TRUE,
'name' => TRUE,
'market' => TRUE,
'transaction_type' => TRUE,
'price' => TRUE,
'currency' => TRUE,
'commission' => TRUE,
'shares' => TRUE,
'purchase_time' => TRUE
];
编辑:添加了额外的数据
这是进入 patchEntity 的数据:
[
'ticker_label' => 'AAPL (Apple Inc.)',
'ticker' => 'AAPL',
'currency' => 'USD',
'market' => 'NASDAQ',
'transaction_type' => 'Buy',
'price' => '10',
'commission' => '10',
'shares' => '10',
'date' => 'Yesterday',
'purchase_time' => 'July 12, 2015 12:00',
'time' => '12:00',
'name' => 'Apple Inc.'
]
这是patchEntity之后的数据是运行:
object(App\Model\Entity\Transaction) {
'portfolio_id' => '43',
'ticker' => 'AAPL',
'currency' => 'USD',
'market' => 'NASDAQ',
'transaction_type' => 'Buy',
'price' => (float) 10,
'commission' => (float) 10,
'shares' => (float) 10,
'purchase_time' => (int) 1436803512,
'name' => 'Apple Inc.',
'[new]' => true,
'[accessible]' => [
'ticker' => true,
'name' => true,
'market' => true,
'transaction_type' => true,
'price' => true,
'currency' => true,
'commission' => true,
'shares' => true,
'purchase_time' => true
],
'[dirty]' => [
'portfolio_id' => true,
'ticker' => true,
'currency' => true,
'market' => true,
'transaction_type' => true,
'price' => true,
'commission' => true,
'shares' => true,
'purchase_time' => true,
'name' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Transactions'
}
可以看到,如果对purchase_time
字段中的Unix时间戳进行转换,则不等于输入。它现在等于当前时间,这在将 NULL
值传递给 Time()
.
问题是 CakePHP 中的 DatetimeType
class 需要规范化格式的输入。作为数组(表单输入)或 ISO 格式的字符串。
由于您以本地化格式提供输入,因此您需要 enable the locale parser、以 ISO 格式发送输入、在将数据转换为日期时间之前对其进行转换,或者扩展 DateTimeType
class 以满足您的需求。
一个简单的方法是使用 Model.beforeMarshal
事件:
$table->eventManager()->on('Model.beforeMarshal', function ($event, $data) {
if (!empty($data['the_time_field']) {
$data['the_time_field'] = new Time($data['the_time_field'])
}
});
重要的是要记住,如果无法正确验证数据或者无法在类型 classes 的帮助下由编组器 "parsed" 将数据设置到实体,这一点很重要。这就是使用 patchEntity 时未调用 setter 的原因。