Symfony 3.2 FOSMessageBundle'... / new'(即撰写新消息)无论我做什么都会抛出错误
I'm not using FOSUserBundle (there's custom user/security code already in place). I've been following the docs here.
After much googling and digging through both Symfony and FOSMessageBundle files, I've come to believe that the issue has something to do with the new NewThreadMessageFormFactory class. It only has one method. If I leave it as is like so
public function create()
{
return $this->formFactory->createNamed(
$this->formName,
$this->formType,
$this->createModelInstance());
}
I get this error Expected argument of type "string", "AppBundle\Service\NewThreadMessageFormType" given
. On the other hand, if I do the following,
public function create()
{
return $this->formFactory->createNamed(
$this->formName,
'AppBundle\Service\NewThreadMessageFormType',
$this->createModelInstance());
}
I get this Could not load type "FOS\UserBundle\Form\Type\UsernameFormType
. Which, of course, doesn't even exist because FOSUserBundle isn't even installed.
I've already spent more than a dozen hours on this. I've learned a lot in the process, but I still can't make the darn thing work...
And my current configuration
//config.yml
fos_message:
db_driver: orm
thread_class: AppBundle\Entity\Thread
message_class: AppBundle\Entity\Message
new_thread_form:
type: app.new_thread_form_type
factory: app.new_thread_form_factory
and...
//services.yml
fos_user.user_to_username_transformer:
alias: app.user_to_username_transformer
app.user_to_username_transformer:
class: AppBundle\Form\DataTransformer\UserToUsernameTransformer
arguments:
type: "service"
id: "doctrine"
app.new_thread_form_type:
class: AppBundle\Service\NewThreadMessageFormType
arguments: ['@app.user_to_username_transformer']
tags:
- {name: form.type}
app.new_thread_form_factory:
class: AppBundle\Service\NewThreadMessageFormFactory
arguments: [
'@form.factory',
'@fos_message.new_thread_form.type',
'%fos_message.new_thread_form.name%',
'%fos_message.new_thread_form.model%'
]
If you are not using the FOSUSerBundle, then you need to do the following:
- Create the UserToUsernameTransformer class as in the guide Using other UserBundles
-
In config.yml:
fos_message: db_driver: orm thread_class: AppBundle\Entity\Thread message_class: AppBundle\Entity\Message new_thread_form: type: AppBundle\Form\Type\NewThreadMessageFormType
-
Register the services:
app.user_to_username_transformer: class: AppBundle\Form\DataTransformer\UserToUsernameTransformer arguments: ['@doctrine'] fos_user.user_to_username_transformer: alias: app.user_to_username_transformer app.form.type.username: class: AppBundle\Form\Type\UsernameFormType arguments: ['@app.user_to_username_transformer'] tags: - { name: form.type }
-
Create a NewThreadMessageFormType form type class to override the default one.
class NewThreadMessageFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('recipient', UsernameFormType::class, array( 'label' => 'recipient', 'translation_domain' => 'FOSMessageBundle', )) ->add('subject', TextType::class, array( 'label' => 'subject', 'translation_domain' => 'FOSMessageBundle', )) ->add('body', TextareaType::class, array( 'label' => 'body', 'translation_domain' => 'FOSMessageBundle', )); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'intention' => 'message', )); } /** * {@inheritdoc} */ public function getBlockPrefix() { return 'new_thread_message'; } }
-
Create a UsernameFormType form type class to handle transforming and displaying the username.
class UsernameFormType extends AbstractType { /** * @var UserToUsernameTransformer */ protected $usernameTransformer; /** * Constructor. * * @param UserToUsernameTransformer $usernameTransformer */ public function __construct(UserToUsernameTransformer $usernameTransformer) { $this->usernameTransformer = $usernameTransformer; } /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->addModelTransformer($this->usernameTransformer); } /** * {@inheritdoc} */ public function getParent() { return TextType::class; } /** * {@inheritdoc} */ public function getBlockPrefix() { return 'toolsets_username_type'; } }
That should get it working.