问题描述
- 产品
- 产品翻译
- ContentBlock
- 产品翻译
我可以很好地添加新产品,但是当我对其进行编辑时,无法加载该表单。它给了我以下错误:
该表单的视图数据应该是ContentBlockDataTransferObject类的实例,但是是ContentBlock类的实例。您可以通过将“ data_class”选项设置为null或添加一个将类ContentBlock的实例转换为ContentBlockDataTransferObject的实例的视图转换器来避免此错误。
将data_class
设置为null似乎没有任何改变。
ProductType.PHP
<?PHP
namespace Backend\Modules\Products\Domain\Product;
use Backend\Core\Language\Language;
use Backend\Modules\MediaLibrary\Domain\MediaGroup\MediaGroupType;
use Backend\Modules\Products\Domain\Categories\Category;
use Backend\Modules\Products\Domain\Divisions\Division;
use Common\Form\CollectionType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Common\Form\ImageType;
use Symfony\Component\Validator\Constraints\Valid;
final class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder,array $options): void
{
$builder->add(
'categories',EntityType::class,[
'class' => Category::class,'multiple' => true,'expanded' => true,'label' => 'lbl.Categories','query_builder' => function (EntityRepository $er) {
return $er->createqueryBuilder('i')
->join('i.translations','t')
->innerJoin(Division::class,'d',Join::WITH,'i.division = d')
->addOrderBy('d.id','ASC')
->addOrderBy('t.title','ASC');
},]
);
$helpTextMessageMainImage = sprintf(
Language::msg('HelpImageFieldWithMaxFileSize'),$this->getUploadMaxFileSize()
);
$helpTextMessageMainImage .= '<br><strong>' . Language::msg('MainImageHelp') . '</strong>';
$builder->add(
'mainImage',ImageType::class,[
'image_class' => MainImage::class,'help_text_message' => $helpTextMessageMainImage,]
);
$builder->add(
'translations',CollectionType::class,[
'entry_type' => ProductTranslationType::class,'error_bubbling' => false,'constraints' => [new Valid()],]
);
$builder->add(
'imagegallery',MediaGroupType::class,[
'required' => false,]
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => ProductDataTransferObject::class]);
}
private function getUploadMaxFileSize(): ?string
{
$uploadMaxFileSize = ini_get('upload_max_filesize');
if ($uploadMaxFileSize === false) {
return null;
}
// reformat if defined as an integer
if (is_numeric($uploadMaxFileSize)) {
return $uploadMaxFileSize / 1024 . 'MB';
}
// reformat if specified in kB
if (mb_strtoupper(mb_substr($uploadMaxFileSize,-1)) === 'K') {
return mb_substr($uploadMaxFileSize,-1) . 'kB';
}
// reformat if specified in MB
if (mb_strtoupper(mb_substr($uploadMaxFileSize,-1)) === 'M') {
return $uploadMaxFileSize . 'B';
}
// reformat if specified in GB
if (mb_strtoupper(mb_substr($uploadMaxFileSize,-1)) === 'G') {
return $uploadMaxFileSize . 'B';
}
return $uploadMaxFileSize;
}
}
ProductTranslationType.PHP
<?PHP
namespace Backend\Modules\Products\Domain\Product;
use Backend\Core\Engine\Model;
use Backend\Core\Language\Language;
use Backend\Form\Type\EditorType;
use Backend\Form\Type\MetaType;
use Backend\Modules\Products\Domain\ContentBlock\ContentBlockType;
use Backend\Modules\Products\Domain\Product\Command\CreateProduct;
use Backend\Modules\Products\Domain\Product\Command\UpdateProduct;
use Backend\Modules\Products\Domain\Product\ProductTranslation\ProductTranslationRepository;
use Common\Form\CollectionType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
final class ProductTranslationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder,array $options): void
{
$builder
->add(
'title',TextType::class,[
'label' => 'lbl.Title',]
)
->add(
'contentBlocks',[
'entry_type' => ContentBlockType::class,'allow_delete' => true,'allow_add' => true,'allow_sequence' => false,'attr' => [
'class' => 'tab-pane tab-pane-collection','data-role' => 'products-content-blocks',],]
)
->addEventListener(
FormEvents::PRE_SET_DATA,function (FormEvent $event) {
/** @var CreateProduct|UpdateProduct $productFormData */
$productFormData = $event->getForm()->getParent()->getParent()->getData();
// Add Meta
$event->getForm()
->add(
'Meta',MetaType::class,[
'detail_url' => Model::getUrlForBlock('Products','ProductDetail'),'base_field_name' => 'title','generate_url_callback_class' => ProductTranslationRepository::class,'generate_url_callback_method' => 'self::getUrl','generate_url_callback_parameters' => [
$event->getData()->getLocale(),$productFormData->hasExistingProduct()
? $productFormData->getProductEntity()->getId() : null,]
);
}
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => ProductTranslationDataTransferObject::class]);
}
}
ContentBlockType.PHP
<?PHP
namespace Backend\Modules\Products\Domain\ContentBlock;
use Backend\Core\Engine\TemplateModifiers;
use Backend\Form\Type\EditorType;
use Common\Form\CollectionType;
use Common\Form\ImageType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Valid;
final class ContentBlockType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder,array $options): void
{
$builder->add(
'sequence',HiddenType::class,'attr' => [
'data-role' => 'sequence'
]
]
);
$builder->add(
'type',ChoiceType::class,[
'label' => 'lbl.Type','choices' => array_map(
function ($contentType) {
return new ContentType($contentType);
},ContentType::POSSIBLE_VALUES
),'choice_label' => function (ContentType $contentType) {
return TemplateModifiers::toLabel($contentType);
},'choice_translation_domain' => false,'choice_value' => function (ContentType $contentType = null) {
return (string) $contentType;
},'attr' => [
'data-role' => 'products-content-blocks-type',]
);
$builder->add(
'text',EditorType::class,[
'label' => 'lbl.Text','required' => false,'attr' => [
'class' => 'inputEditor','data-show' => 'type-text',]
);
$builder->add(
'image',[
'label' => 'lbl.Image','image_class' => Image::class,'show_remove_image' => false,]
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => ContentBlockDataTransferObject::class]);
}
}
ProductAdd.PHP 操作
<?PHP
namespace Backend\Modules\Products\Actions;
use Backend\Core\Engine\Base\ActionAdd;
use Backend\Core\Language\Language;
use Backend\Core\Language\Locale;
use Backend\Modules\Products\Domain\Product\Command\CreateProduct;
use Backend\Modules\Products\Domain\Product\Command\CreateProductHandler;
use Backend\Modules\Products\Domain\Product\ProductType;
use Backend\Core\Engine\Model as BackendModel;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormError;
final class ProductAdd extends ActionAdd
{
public function execute(): void
{
parent::execute();
$form = $this->getForm();
if (!$form->isSubmitted() || !$form->isValid()) {
$this->template->assign('activeTranslationTab','tab' . ucfirst(Locale::workingLocale()));
$this->template->assign('locale',Locale::workingLocale());
$this->template->assign('form',$form->createView());
$this->template->assign('backLink',$this->getBackLink());
$this->template->assign('imagegallery',$form->getData()->imagegallery);
$this->parse();
$this->display();
return;
}
$this->handleForm($form);
}
private function handleForm(Form $form): void
{
/** @var CreateProduct $product */
$product = $form->getData();
// Handle the Product create
$this->get('command_bus')->handle($product);
$this->redirect(
$this->getBackLink(
[
'report' => 'added','var' => $product->translations[(string) Locale::workingLocale()]->title,]
)
);
}
private function getForm(): Form
{
$form = $this->createForm(ProductType::class,new CreateProduct());
$form->handleRequest($this->getRequest());
return $form;
}
private function getBackLink(array $parameters = []): string
{
return BackendModel::createUrlForAction(
'ProductsIndex',null,$parameters
);
}
}
ProductEdit.PHP 操作
<?PHP
namespace Backend\Modules\Products\Actions;
use Backend\Core\Engine\Base\ActionEdit;
use Backend\Core\Language\Language;
use Backend\Core\Language\Locale;
use Backend\Form\Type\DeleteType;
use Backend\Modules\Products\Domain\Product\Command\UpdateProductHandler;
use Backend\Modules\Products\Domain\Product\Product;
use Backend\Modules\Products\Domain\Product\Command\UpdateProduct;
use Backend\Core\Engine\Model as BackendModel;
use Backend\Modules\Products\Domain\Product\ProductRepository;
use Backend\Modules\Products\Domain\Product\ProductType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormError;
final class ProductEdit extends ActionEdit
{
public function execute(): void
{
parent::execute();
/** @var Product $product */
$product = $this->getProduct();
/** @var Form $form */
$form = $this->getForm($product);
$deleteForm = $this->createForm(
DeleteType::class,['id' => $product->getId()],[
'module' => $this->getModule(),'action' => 'ProductDelete',]
);
$this->template->assign('deleteForm',$deleteForm->createView());
if (!$form->isSubmitted() || !$form->isValid()) {
$this->template->assign('activeTranslationTab',$form->createView());
$this->template->assign('product',$product);
$this->template->assign('imagegallery',$form->getData()->imagegallery);
$this->parse();
$this->display();
return;
}
/** @var UpdateProduct $updateProduct */
$updateProduct = $form->getData();
// Handle the Product update
$this->get('command_bus')->handle($updateProduct);
$this->redirect(
$this->getBackLink(
[
'report' => 'edited','var' => $updateProduct->translations[(string)Locale::workingLocale()]->title,'highlight' => 'row-' . $updateProduct->getProductEntity()->getId(),]
)
);
}
private function getProduct(): Product
{
try {
/** @return Product */
return $this->get(ProductRepository::class)->findOneById($this->getRequest()->query->get('id'));
} catch (\Exception $e) {
$this->redirect(
$this->getBackLink(
[
'error' => 'non-existing'
]
)
);
}
}
private function getBackLink(array $parameters = []): string
{
return BackendModel::createUrlForAction(
'ProductsIndex',$parameters
);
}
private function getForm(Product $product): Form
{
$form = $this->createForm(ProductType::class,new UpdateProduct($product));
$form->handleRequest($this->getRequest());
return $form;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)