加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > PHP > 正文

php – Symfony2表单和集合 – Order,OrderItem实现

发布时间:2020-05-25 09:06:19 所属栏目:PHP 来源:互联网
导读:因此,我今天花了大约5或6个小时与Symfony2表格进行斗争,并且我希望得到社区其他成员的一些建议.我已经尝试了3种不同的方法来实现我所追求的并且没有成功.我已经阅读了文档,谷歌搜索了所有内容,问了其他人,而且比起初时我只有一点点好转. 我的用例 我正在建立

因此,我今天花了大约5或6个小时与Symfony2表格进行斗争,并且我希望得到社区其他成员的一些建议.我已经尝试了3种不同的方法来实现我所追求的并且没有成功.我已经阅读了文档,谷歌搜索了所有内容,问了其他人,而且比起初时我只有一点点好转.

我的用例

我正在建立一个可以订购门票的系统.但核心问题是如何设计系统的订单部分.

>票证有一个名称,以及它可用的开始和结束日期(其他东西也是如此,但让我们保持示例简单.
>订单可能会选择多个故障单,并且每个故障单都有一个数量.
>订单有客户.这部分很好,工作花花公子!

在阅读并尝试不同的事情后,我收集了代表订单的票和数量,我需要另一个实体OrderTicket对应于https://github.com/beberlei/AcmePizzaBundle的OrderItem,而Pizza是我的票.

> OrderTicket有票和数量.

在我创建订单的订单页面上,我想要以下内容:

>客户详细信息表 – 姓名,电子邮件,地址.这部分工作正常.
>门票的表格.我希望在文本框或字符串中显示故障单名称;不在选择框中(现在正在发生的事情).我希望在故障单名称旁边指定数量.如果没有设置数量,则表示未选择故障单.
>根据今天的日期,门票应该在可用的位置进行过滤 – 这可以通过在带有查询构建器闭包的表单类型上使用自定义存储库方法在其他地方(在创建它们的后端管理中)实现.

我的后端

Order / OrderTicket / Ticket设计主要基于https://github.com/beberlei/AcmePizzaBundle

/**
 * @ORMEntity(repositoryClass="FooBackendBundleEntityTicketsRepository")
 * @ORMHasLifecycleCallbacks
 * @ORMTable(name="tickets")
 */
class Tickets
{
    // id fields and others

    /**
     * @AssertNotBlank
     * @ORMColumn(type="string",nullable=true)
     */
    protected $name;

    /**
     * @ORMColumn(type="date",name="available_from",nullable=true)
     */    
    protected $availableFrom;

    /**
     * @ORMColumn(type="date",name="available_to",nullable=true)
     */    
    protected $availableTo;
}

OrderTicket

/**
 * @ORMTable()
 * @ORMEntity
 */
class OrderTicket
{
    // id field

    /**
     * @ORMColumn(name="quantity",type="integer")
     */
    private $quantity;

    /**
     * @ORMManyToOne(targetEntity="Tickets")
     */
    protected $ticket;

    /**
     * @ORMManyToOne(targetEntity="Orders",inversedBy="tickets")
     */
    protected $order;

    // getters and setters for quantity,ticket and order
}

订购

/**
 * @ORMEntity
 * @ORMHasLifecycleCallbacks
 * @ORMTable(name="orders")
 */
class Orders
{   
    // id field and other stuff

    /**
     * @ORMOneToMany(targetEntity="OrderTicket",mappedBy="order",cascade={"persist"})
     **/
    protected $tickets;

    /**
     * @ORMManyToOne(targetEntity="Customer",cascade={"persist"})
     */
    protected $customer;

    public function __construct()
    {
        $this->tickets = new DoctrineCommonCollectionsArrayCollection();
    }

    // getters,setters,add for Tickets and Customer
}

顾客

/**
 * @ORMTable()
 * @ORMEntity
 */
class Customer
{
    // id,name,email,address fields

}

这会创建一个类似的模式(表命名差异来自自动生成):

CREATE TABLE `tickets` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,`available_from` date DEFAULT NULL,`available_to` date DEFAULT NULL,PRIMARY KEY (`id`)
);
CREATE TABLE `Customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`address` longtext COLLATE utf8_unicode_ci NOT NULL,PRIMARY KEY (`id`)
);
CREATE TABLE `OrderTicket` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`ticket_id` int(11) DEFAULT NULL,`order_id` int(11) DEFAULT NULL,`quantity` int(11) NOT NULL,PRIMARY KEY (`id`)
);
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`customer_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
);

形式

class CustomerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('email')
            ->add('name')
            ->add('address')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'FooBackendBundleEntityCustomer'
        ));
    }

    public function getName()
    {
        return 'foo_backendbundle_customertype';
    }
}

class OrderTicketType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('quantity','integer')
            ->add('ticket')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'FooBackendBundleEntityOrderTicket'
        ));
    }

    public function getName()
    {
        return 'foo_backendbundle_ordertickettype';
    }
}

class OrdersType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('customer',new CustomerType())
            ->add('tickets','collection',array(
                'type' => new OrderTicketType(),'allow_add'    => true,'allow_delete' => true,'prototype'    => true,))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'FooBackendBundleEntityOrders',));
    }

    public function getName()
    {
        return 'foo_backendbundle_orderstype';
    }
}

表格

<form action="{{ path('index') }}" method="post" {{ form_enctype(form) }}>
    <h3>Tickets</h3>

    {{ form_errors(form) }}

    <table>
        <thead>
            <tr>
                <td>Ticket</td>
                <td>Quantity</td>
        </thead>
        <tbody>
            {% for ticketrow in form.tickets %}
            <tr>
                <td>{{ form_widget(ticketrow.ticket) }}</td>
                <td>{{ form_widget(ticketrow.quantity) }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <h3>Customer</h3>

    {% for customer in form.customer %}
        {{ form_row(customer) }}
    {% endfor %}
</form>

最后是控制器

class DefaultController extends Controller
{
    /**
     * @Route("/",name="index")
     * @Template()
     */
    public function indexAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        // IMPORTANT - the Tickets are prefiltered for active Tickets,these have to be injected into the Order atm. In other places I use this method on the query builder
        $tickets = $em->getRepository('FooBackendBundle:Tickets')->findActive();

        // check no tickets

        $order = new Orders();

        // To prepopulate the order with the available tickets,we have to do it like this,due to it being a collection,// rather than using the forms query_builder like everywhere else
        foreach($tickets as $ticket) {
            $ot = new OrderTicket();
            $ot->setTicket($ticket);
            $ot->setQuantity(0);
            $ot->setOrder($order);
            $order->addTicket($ot);
        }

        $form = $this->createForm(new OrdersType(),$order);

        if ($request->isMethod('POST')) {

            $form->bind($request);

            // IMPORTANT here I have to remove the previously added Tickets where the quantity is 0 - as they're not wanted in the Order.  Is there a better way to do this?
            // if the quantity of Ticket is 0,do not add to order
            // note we use the validation callback in Order to check total quantity of OrderTickets is > 0
            $order->removeTicketsWithNoQuantity();

            if ($form->isValid()) {

                $em->persist($order);
                $em->flush();

                return $this->redirect($this->generateUrl('order_show',array('id' => $order->getId())));
            }
        }

        return array('form' => $form->createView());
    }
}

摘要

这可以正常保存订单,但我不确定这是正确的方式来做我想要的,它不会显示我想要的.

您可以在下面的图像中看到它的外观和顺序如何通过.值得注意的是,在每张Ticket下拉列表中,其余的门票都是活跃的.

订单页面:

保存后的订单摘要页面:

显示的3个门票是已过滤的门票,我只想在窗体上使用这些门票.我只想看到门票名称,而不是可编辑的下降.

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读