These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of EC-CUBE |
||
5 | * |
||
6 | * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. |
||
7 | * |
||
8 | * http://www.ec-cube.co.jp/ |
||
9 | * |
||
10 | * For the full copyright and license information, please view the LICENSE |
||
11 | * file that was distributed with this source code. |
||
12 | */ |
||
13 | |||
14 | namespace Eccube\Form\Type\Shopping; |
||
15 | |||
16 | use Doctrine\Common\Collections\ArrayCollection; |
||
17 | use Eccube\Entity\Delivery; |
||
18 | use Eccube\Entity\Order; |
||
19 | use Eccube\Entity\Payment; |
||
20 | use Eccube\Repository\BaseInfoRepository; |
||
21 | use Eccube\Repository\DeliveryRepository; |
||
22 | use Eccube\Repository\OrderRepository; |
||
23 | use Eccube\Repository\PaymentRepository; |
||
24 | use Eccube\Request\Context; |
||
25 | use Symfony\Bridge\Doctrine\Form\Type\EntityType; |
||
26 | use Symfony\Component\Form\AbstractType; |
||
27 | use Symfony\Component\Form\Extension\Core\Type\CollectionType; |
||
28 | use Symfony\Component\Form\Extension\Core\Type\HiddenType; |
||
29 | use Symfony\Component\Form\Extension\Core\Type\IntegerType; |
||
30 | use Symfony\Component\Form\Extension\Core\Type\TextareaType; |
||
31 | use Symfony\Component\Form\FormBuilderInterface; |
||
32 | use Symfony\Component\Form\FormEvent; |
||
33 | use Symfony\Component\Form\FormEvents; |
||
34 | use Symfony\Component\Form\FormInterface; |
||
35 | use Symfony\Component\OptionsResolver\OptionsResolver; |
||
36 | use Symfony\Component\Validator\Constraints\Length; |
||
37 | use Symfony\Component\Validator\Constraints\NotBlank; |
||
38 | use Symfony\Component\Validator\Constraints\Regex; |
||
39 | |||
40 | class OrderType extends AbstractType |
||
41 | { |
||
42 | /** |
||
43 | * @var OrderRepository |
||
44 | */ |
||
45 | protected $orderRepository; |
||
46 | |||
47 | /** |
||
48 | * @var DeliveryRepository |
||
49 | */ |
||
50 | protected $deliveryRepository; |
||
51 | |||
52 | /** |
||
53 | * @var PaymentRepository |
||
54 | */ |
||
55 | protected $paymentRepository; |
||
56 | |||
57 | /** |
||
58 | * @var BaseInfoRepository |
||
59 | 50 | */ |
|
60 | protected $baseInfoRepository; |
||
61 | |||
62 | /** |
||
63 | * @var Context |
||
64 | 50 | */ |
|
65 | 50 | protected $requestContext; |
|
66 | 50 | ||
67 | /** |
||
68 | * OrderType constructor. |
||
69 | * |
||
70 | * @param OrderRepository $orderRepository |
||
71 | * @param DeliveryRepository $deliveryRepository |
||
72 | 50 | * @param PaymentRepository $paymentRepository |
|
73 | * @param BaseInfoRepository $baseInfoRepository |
||
74 | * @param Context $requestContext |
||
75 | 50 | */ |
|
76 | 50 | public function __construct( |
|
77 | 50 | OrderRepository $orderRepository, |
|
78 | DeliveryRepository $deliveryRepository, |
||
79 | 50 | PaymentRepository $paymentRepository, |
|
80 | BaseInfoRepository $baseInfoRepository, |
||
81 | 50 | Context $requestContext |
|
82 | ) { |
||
83 | $this->orderRepository = $orderRepository; |
||
84 | $this->deliveryRepository = $deliveryRepository; |
||
85 | 50 | $this->paymentRepository = $paymentRepository; |
|
86 | 50 | $this->baseInfoRepository = $baseInfoRepository; |
|
87 | 50 | $this->requestContext = $requestContext; |
|
88 | } |
||
89 | 50 | ||
90 | 50 | /** |
|
91 | * {@inheritdoc} |
||
92 | 50 | */ |
|
93 | 50 | public function buildForm(FormBuilderInterface $builder, array $options) |
|
94 | { |
||
95 | // ShoppingController::checkoutから呼ばれる場合は, フォーム項目の定義をスキップする. |
||
96 | 50 | if ($options['skip_add_form']) { |
|
97 | return; |
||
98 | } |
||
99 | |||
100 | 50 | $builder->add('message', TextareaType::class, [ |
|
101 | 50 | 'required' => false, |
|
102 | 50 | 'constraints' => [ |
|
103 | new Length(['min' => 0, 'max' => 3000]), |
||
104 | 50 | ], |
|
105 | ])->add('Shippings', CollectionType::class, [ |
||
106 | 'entry_type' => ShippingType::class, |
||
107 | 50 | 'by_reference' => false, |
|
108 | 50 | ])->add('redirect_to', HiddenType::class, [ |
|
109 | 50 | 'mapped' => false, |
|
110 | ]); |
||
111 | 50 | ||
112 | if ($this->baseInfoRepository->get()->isOptionPoint() && $this->requestContext->getCurrentUser()) { |
||
113 | 50 | $builder->add('use_point', IntegerType::class, [ |
|
114 | 50 | 'required' => false, |
|
115 | 50 | 'constraints' => [ |
|
116 | new NotBlank(), |
||
117 | 50 | new Regex([ |
|
118 | 'pattern' => "/^\d+$/u", |
||
119 | 'message' => 'form_error.numeric_only', |
||
120 | ]), |
||
121 | new Length(['max' => 11]), |
||
122 | 50 | ], |
|
123 | 50 | ]); |
|
124 | 50 | } |
|
125 | |||
126 | 50 | // 支払い方法のプルダウンを生成 |
|
127 | 50 | $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) { |
|
128 | /** @var Order $Order */ |
||
129 | $Order = $event->getData(); |
||
130 | if (null === $Order || !$Order->getId()) { |
||
131 | return; |
||
132 | 50 | } |
|
133 | |||
134 | 50 | $Deliveries = $this->getDeliveries($Order); |
|
135 | 50 | $Payments = $this->getPayments($Deliveries); |
|
136 | 50 | $Payments = $this->filterPayments($Payments, $Order->getPaymentTotal()); |
|
137 | 50 | ||
138 | $form = $event->getForm(); |
||
139 | $this->addPaymentForm($form, $Payments, $Order->getPayment()); |
||
140 | 50 | }); |
|
141 | 50 | ||
142 | // 支払い方法のプルダウンを生成(Submit時) |
||
143 | // 配送方法の選択によって使用できる支払い方法がかわるため, フォームを再生成する. |
||
144 | 50 | $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { |
|
145 | /** @var Order $Order */ |
||
146 | 50 | $Order = $event->getForm()->getData(); |
|
147 | $data = $event->getData(); |
||
148 | 50 | ||
149 | 50 | $Deliveries = []; |
|
150 | 50 | if (!empty($data['Shippings'])) { |
|
151 | 50 | foreach ($data['Shippings'] as $Shipping) { |
|
152 | if (!empty($Shipping['Delivery'])) { |
||
153 | 50 | $Delivery = $this->deliveryRepository->find($Shipping['Delivery']); |
|
154 | 50 | if ($Delivery) { |
|
155 | 50 | $Deliveries[] = $Delivery; |
|
156 | 50 | } |
|
157 | } |
||
158 | } |
||
159 | } |
||
160 | |||
161 | 50 | $Payments = $this->getPayments($Deliveries); |
|
162 | $Payments = $this->filterPayments($Payments, $Order->getPaymentTotal()); |
||
163 | 50 | ||
164 | $form = $event->getForm(); |
||
165 | $this->addPaymentForm($form, $Payments); |
||
166 | 50 | }); |
|
167 | |||
168 | $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { |
||
169 | /** @var Order $Order */ |
||
170 | $Order = $event->getData(); |
||
171 | 50 | $Payment = $Order->getPayment(); |
|
172 | 50 | if ($Payment && $Payment->getMethod()) { |
|
0 ignored issues
–
show
|
|||
173 | 50 | $Order->setPaymentMethod($Payment->getMethod()); |
|
174 | } |
||
175 | 25 | }); |
|
176 | } |
||
177 | 25 | ||
178 | 25 | public function configureOptions(OptionsResolver $resolver) |
|
179 | { |
||
180 | 25 | $resolver->setDefaults( |
|
181 | 25 | [ |
|
182 | 'data_class' => 'Eccube\Entity\Order', |
||
183 | 'skip_add_form' => false, |
||
184 | 50 | ] |
|
185 | ); |
||
186 | } |
||
187 | |||
188 | 50 | public function getBlockPrefix() |
|
189 | { |
||
190 | 50 | return '_shopping_order'; |
|
191 | } |
||
192 | 50 | ||
193 | private function addPaymentForm(FormInterface $form, array $choices, Payment $data = null) |
||
194 | { |
||
195 | $message = trans('front.shopping.payment_method_unselected'); |
||
196 | |||
197 | 50 | if (empty($choices)) { |
|
198 | $message = trans('front.shopping.payment_method_not_fount'); |
||
199 | 50 | } |
|
200 | |||
201 | $form->add('Payment', EntityType::class, [ |
||
202 | 'class' => Payment::class, |
||
203 | 'choice_label' => 'method', |
||
204 | 'expanded' => true, |
||
205 | 'multiple' => false, |
||
206 | 'placeholder' => false, |
||
207 | 'constraints' => [ |
||
208 | new NotBlank(['message' => $message]), |
||
209 | ], |
||
210 | 'choices' => $choices, |
||
211 | 'data' => $data, |
||
212 | 'invalid_message' => $message, |
||
213 | ]); |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * 出荷に紐づく配送方法を取得する. |
||
218 | * |
||
219 | * @param Order $Order |
||
220 | * |
||
221 | * @return Delivery[] |
||
222 | */ |
||
223 | private function getDeliveries(Order $Order) |
||
224 | { |
||
225 | $Deliveries = []; |
||
226 | foreach ($Order->getShippings() as $Shipping) { |
||
227 | $Delivery = $Shipping->getDelivery(); |
||
228 | if ($Delivery->isVisible()) { |
||
229 | $Deliveries[] = $Shipping->getDelivery(); |
||
230 | } |
||
231 | } |
||
232 | |||
233 | return array_unique($Deliveries); |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * 配送方法に紐づく支払い方法を取得する |
||
238 | * 各配送方法に共通する支払い方法のみ返す. |
||
239 | * |
||
240 | * @param Delivery[] $Deliveries |
||
241 | * |
||
242 | * @return ArrayCollection |
||
243 | */ |
||
244 | private function getPayments($Deliveries) |
||
245 | { |
||
246 | $PaymentsByDeliveries = []; |
||
247 | foreach ($Deliveries as $Delivery) { |
||
248 | $PaymentOptions = $Delivery->getPaymentOptions(); |
||
249 | foreach ($PaymentOptions as $PaymentOption) { |
||
250 | /** @var Payment $Payment */ |
||
251 | $Payment = $PaymentOption->getPayment(); |
||
252 | if ($Payment->isVisible()) { |
||
253 | $PaymentsByDeliveries[$Delivery->getId()][] = $Payment; |
||
254 | } |
||
255 | } |
||
256 | } |
||
257 | |||
258 | if (empty($PaymentsByDeliveries)) { |
||
259 | return new ArrayCollection(); |
||
260 | } |
||
261 | |||
262 | $i = 0; |
||
263 | $PaymentsIntersected = []; |
||
264 | foreach ($PaymentsByDeliveries as $Payments) { |
||
265 | if ($i === 0) { |
||
266 | $PaymentsIntersected = $Payments; |
||
267 | } else { |
||
268 | $PaymentsIntersected = array_intersect($PaymentsIntersected, $Payments); |
||
269 | } |
||
270 | $i++; |
||
271 | } |
||
272 | |||
273 | return new ArrayCollection($PaymentsIntersected); |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * 支払い方法の利用条件でフィルタをかける. |
||
278 | * |
||
279 | * @param ArrayCollection $Payments |
||
280 | * @param $total |
||
281 | * |
||
282 | * @return Payment[] |
||
283 | */ |
||
284 | private function filterPayments(ArrayCollection $Payments, $total) |
||
285 | { |
||
286 | $PaymentArrays = $Payments->filter(function (Payment $Payment) use ($total) { |
||
287 | $min = $Payment->getRuleMin(); |
||
288 | $max = $Payment->getRuleMax(); |
||
289 | |||
290 | if (null !== $min && $total < $min) { |
||
291 | return false; |
||
292 | } |
||
293 | |||
294 | if (null !== $max && $total > $max) { |
||
295 | return false; |
||
296 | } |
||
297 | |||
298 | return true; |
||
299 | })->toArray(); |
||
300 | usort($PaymentArrays, function (Payment $a, Payment $b) { |
||
301 | return $a->getSortNo() < $b->getSortNo() ? 1 : -1; |
||
302 | }); |
||
303 | |||
304 | return $PaymentArrays; |
||
305 | } |
||
306 | } |
||
307 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: