管理货币类型以编辑实体
Managing currency type to edit Entity
我正在使用包含 价格 信息的费用实体,为此我选择将金额 (int) 从货币 (字符串) 中分离出来。
/**
* @var integer
*
* @ORM\Column(name="price_amount", type="integer")
*/
private $priceAmount;
/**
* @var string
*
* @ORM\Column(name="price_currency", type="string", length=10)
*/
private $priceCurrency;
我正在使用 MoneyBundle(通过 TBBC 捆绑包)让 creation 表单显示支持的货币列表并让用户选择正确的货币。表单验证后,价格货币作为字符串存储在数据库中。
// ExpenseType.php
[...]
use Tbbc\MoneyBundle\Form\Type\CurrencyType;
[...]
$builder
->add('priceAmount', NumberType::class, array(
'label' => 'Amount spent',
'attr' => array(
'placeholder' => "Amount",
'autocomplete' => 'off'
)))
->add('priceCurrency', CurrencyType::class, array(
'label' => 'Currency'
))
我正在尝试创建另一种表单类型 ExpenseEditType(扩展上面的 ExpenseType),这将帮助用户修改 金额(金额本身 + 其货币);显然,当我加载 ExpenseEditType 表单时,symfony 试图从我的学说实体创建一个 CurrencyType,但它只在数据库中找到一个字符串(例如 "CAD"、"EUR" 等)。
$form = $this->createForm(new ExpenseEditType(), $expense);
引发异常:
Expected argument of type "Currency", "string" given
我的问题是:我怎样才能创建与创建表单相同类型的表单,并要求 symfony 显示相同的货币列表,并选择它在我的 price.currency 中找到的默认值场地?
我正在考虑 2 个选项(但我可能完全错了):
- 使用 DataTransformer,但只是从 Symfony 开始,我真的对这类东西一无所知
- 在我的 Expense 实体中有一个额外的 Money 字段,它将在我的 2 个独立字段(金额/货币)之上的一个 Money 字段中存储金额+货币信息;我想坚持使用这两个单独的字段,以便更好地查询数据库中的可能性和易用性。
非常感谢您的帮助和建议!
文森特
感谢 Heah 和 Jason 的建议,我采用了 DataTransformer 解决方案并且运行良好 :) 我的代码基于 official documentation。
查找下面的结果:
StringToCurrencyTransformer.php
<?php
namespace VP\AccountsBundle\Form\DataTransformer;
// some uses
class StringToCurrencyTransformer implements DataTransformerInterface {
private $manager;
public function __construct(ObjectManager $manager) {
$this->manager = $manager;
}
/**
* Transforms a String (currency_str) to a Currency
*
* @param String|null $currency_str
* @return Currency The Currency Object
* @throws UnknownCurrencyException if Currency is not found
*/
public function transform($currency_str) {
if (null === $currency_str) {
return;
}
try {
$currency = new Currency($currency_str);
} catch (UnknownCurrencyException $ex) {
throw new TransformationFailedException(
sprintf(
'The currency "%s" does not exist', $currency_str
));
}
return $currency;
}
/**
* Transforms a Currency (currency) to a String
* @param Currency $currency
* @return String|null The ISO code of the currency
* @throws TransformationFailedException if currency is not found
*/
public function reverseTransform($currency) {
// if no currency provided
if (!$currency) {
return;
}
$currency_str = $currency->getName();
return $currency_str;
}
}
我的新ExpenseEditType.php
<?php
// some uses
class ExpenseEditType extends ExpenseType {
private $manager;
public function __construct(ObjectManager $manager) {
$this->manager = $manager;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder->remove('submitnew')
->remove('priceCurrency')
->add('priceCurrency', CurrencyType::class, array(
'label' => 'Devise',
'invalid_message' => 'Currency not found'
))
->add('submitnew', SubmitType::class, array(
'label' => 'Edit expense',
'attr' => array(
'class' => 'btn btn-primary',
)
));
$builder->get('priceCurrency')
->addModelTransformer(new StringToCurrencyTransformer($this->manager));
}
/**
* @return string
*/
public function getName() {
return 'vp_accountsbundle_expenseedit';
}
我的service.yml:
services:
app.form.type.expenseedit:
class: VP\AccountsBundle\Form\ExpenseEditType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type }
我来自控制器的呼叫:
$form = $this->createForm(ExpenseEditType::class, $expense);
再次感谢大家!
我正在使用包含 价格 信息的费用实体,为此我选择将金额 (int) 从货币 (字符串) 中分离出来。
/**
* @var integer
*
* @ORM\Column(name="price_amount", type="integer")
*/
private $priceAmount;
/**
* @var string
*
* @ORM\Column(name="price_currency", type="string", length=10)
*/
private $priceCurrency;
我正在使用 MoneyBundle(通过 TBBC 捆绑包)让 creation 表单显示支持的货币列表并让用户选择正确的货币。表单验证后,价格货币作为字符串存储在数据库中。
// ExpenseType.php
[...]
use Tbbc\MoneyBundle\Form\Type\CurrencyType;
[...]
$builder
->add('priceAmount', NumberType::class, array(
'label' => 'Amount spent',
'attr' => array(
'placeholder' => "Amount",
'autocomplete' => 'off'
)))
->add('priceCurrency', CurrencyType::class, array(
'label' => 'Currency'
))
我正在尝试创建另一种表单类型 ExpenseEditType(扩展上面的 ExpenseType),这将帮助用户修改 金额(金额本身 + 其货币);显然,当我加载 ExpenseEditType 表单时,symfony 试图从我的学说实体创建一个 CurrencyType,但它只在数据库中找到一个字符串(例如 "CAD"、"EUR" 等)。
$form = $this->createForm(new ExpenseEditType(), $expense);
引发异常:
Expected argument of type "Currency", "string" given
我的问题是:我怎样才能创建与创建表单相同类型的表单,并要求 symfony 显示相同的货币列表,并选择它在我的 price.currency 中找到的默认值场地?
我正在考虑 2 个选项(但我可能完全错了): - 使用 DataTransformer,但只是从 Symfony 开始,我真的对这类东西一无所知 - 在我的 Expense 实体中有一个额外的 Money 字段,它将在我的 2 个独立字段(金额/货币)之上的一个 Money 字段中存储金额+货币信息;我想坚持使用这两个单独的字段,以便更好地查询数据库中的可能性和易用性。
非常感谢您的帮助和建议! 文森特
感谢 Heah 和 Jason 的建议,我采用了 DataTransformer 解决方案并且运行良好 :) 我的代码基于 official documentation。
查找下面的结果:
StringToCurrencyTransformer.php
<?php
namespace VP\AccountsBundle\Form\DataTransformer;
// some uses
class StringToCurrencyTransformer implements DataTransformerInterface {
private $manager;
public function __construct(ObjectManager $manager) {
$this->manager = $manager;
}
/**
* Transforms a String (currency_str) to a Currency
*
* @param String|null $currency_str
* @return Currency The Currency Object
* @throws UnknownCurrencyException if Currency is not found
*/
public function transform($currency_str) {
if (null === $currency_str) {
return;
}
try {
$currency = new Currency($currency_str);
} catch (UnknownCurrencyException $ex) {
throw new TransformationFailedException(
sprintf(
'The currency "%s" does not exist', $currency_str
));
}
return $currency;
}
/**
* Transforms a Currency (currency) to a String
* @param Currency $currency
* @return String|null The ISO code of the currency
* @throws TransformationFailedException if currency is not found
*/
public function reverseTransform($currency) {
// if no currency provided
if (!$currency) {
return;
}
$currency_str = $currency->getName();
return $currency_str;
}
}
我的新ExpenseEditType.php
<?php
// some uses
class ExpenseEditType extends ExpenseType {
private $manager;
public function __construct(ObjectManager $manager) {
$this->manager = $manager;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder->remove('submitnew')
->remove('priceCurrency')
->add('priceCurrency', CurrencyType::class, array(
'label' => 'Devise',
'invalid_message' => 'Currency not found'
))
->add('submitnew', SubmitType::class, array(
'label' => 'Edit expense',
'attr' => array(
'class' => 'btn btn-primary',
)
));
$builder->get('priceCurrency')
->addModelTransformer(new StringToCurrencyTransformer($this->manager));
}
/**
* @return string
*/
public function getName() {
return 'vp_accountsbundle_expenseedit';
}
我的service.yml:
services:
app.form.type.expenseedit:
class: VP\AccountsBundle\Form\ExpenseEditType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type }
我来自控制器的呼叫:
$form = $this->createForm(ExpenseEditType::class, $expense);
再次感谢大家!