Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like OrderItem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use OrderItem, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
31 | class OrderItem implements IOrderItem |
||
32 | { |
||
33 | use TPayload, TIdentity, TOrderItemDescription, TFeeContainer, TEstimatedDeliveryDate, |
||
34 | TGifting, TItemCustomization, TCustomAttributeContainer, TNamedDeliveryDate; |
||
35 | |||
36 | const ROOT_NODE = 'OrderItem'; |
||
37 | |||
38 | /** @var int */ |
||
39 | protected $lineNumber; |
||
40 | /** @var bool */ |
||
41 | protected $isHiddenGift; |
||
42 | /** @var string */ |
||
43 | protected $taxAndDutyDisplayType; |
||
44 | /** @var int */ |
||
45 | protected $subscriptionId; |
||
46 | /** @var string */ |
||
47 | protected $itemId; |
||
48 | /** @var float */ |
||
49 | protected $quantity; |
||
50 | /** @var string */ |
||
51 | protected $screenSize; |
||
52 | /** @var string */ |
||
53 | protected $department; |
||
54 | /** @var IPriceGroup */ |
||
55 | protected $merchandisePricing; |
||
56 | /** @var IPriceGroup */ |
||
57 | protected $shippingPricing; |
||
58 | /** @var IPriceGroup */ |
||
59 | protected $dutyPricing; |
||
60 | /** @var string */ |
||
61 | protected $shippingProgram; |
||
62 | /** @var string */ |
||
63 | protected $shippingProgramAuthToken; |
||
64 | /** @var string */ |
||
65 | protected $shippingMethod; |
||
66 | /** @var string */ |
||
67 | protected $shippingMethodDisplayText; |
||
68 | /** @var IStoreFrontDetails */ |
||
69 | protected $storeFrontDetails; |
||
70 | /** @var IProxyPickupDetails */ |
||
71 | protected $proxyPickupDetails; |
||
72 | /** @var string */ |
||
73 | protected $fulfillmentChannel; |
||
74 | /** @var string */ |
||
75 | protected $deliveryInstructions; |
||
76 | /** @var string */ |
||
77 | protected $vendorId; |
||
78 | /** @var string */ |
||
79 | protected $vendorName; |
||
80 | /** @var string */ |
||
81 | protected $shopRunnerMessage; |
||
82 | /** @var string */ |
||
83 | protected $serialNumber; |
||
84 | /** @var string */ |
||
85 | protected $giftRegistryCancelUrl; |
||
86 | /** @var string */ |
||
87 | protected $reservationId; |
||
88 | |||
89 | /** |
||
90 | * @param IValidatorIterator |
||
91 | * @param ISchemaValidator |
||
92 | * @param IPayloadMap |
||
93 | * @param LoggerInterface |
||
94 | * @param IPayload |
||
95 | * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
||
96 | */ |
||
97 | public function __construct( |
||
98 | IValidatorIterator $validators, |
||
99 | ISchemaValidator $schemaValidator, |
||
100 | IPayloadMap $payloadMap, |
||
101 | LoggerInterface $logger, |
||
102 | IPayload $parentPayload = null |
||
103 | ) { |
||
104 | $this->logger = $logger; |
||
|
|||
105 | $this->validators = $validators; |
||
106 | $this->payloadMap = $payloadMap; |
||
107 | $this->parentPayload = $parentPayload; |
||
108 | $this->payloadFactory = new PayloadFactory; |
||
109 | |||
110 | $this->extractionPaths = [ |
||
111 | 'id' => 'string(@id)', |
||
112 | 'lineNumber' => 'string(@webLineId)', |
||
113 | 'itemId' => 'string(x:ItemId)', |
||
114 | 'quantity' => 'number(x:Quantity)', |
||
115 | 'includeGiftWrapping' => 'boolean(x:Gifting/x:GiftCard)', |
||
116 | ]; |
||
117 | $this->optionalExtractionPaths = [ |
||
118 | 'subscriptionId' => '@subscriptionId', |
||
119 | 'taxAndDutyDisplayType' => '@taxAndDutyDisplay', |
||
120 | 'description' => 'x:Description/x:Description', |
||
121 | 'color' => 'x:Description/x:Color', |
||
122 | 'colorId' => 'x:Description/x:Color/@id', |
||
123 | 'size' => 'x:Description/x:Size', |
||
124 | 'sizeId' => 'x:Description/x:Size/@id', |
||
125 | 'screenSize' => 'x:Description/x:ScreenSize', |
||
126 | 'department' => 'x:Department', |
||
127 | 'shippingProgram' => 'x:ShippingProgram', |
||
128 | 'shippingProgramAuthToken' => 'x:ShippingProgram/@authToken', |
||
129 | 'shippingMethod' => 'x:ShippingMethod', |
||
130 | 'shippingMethodDisplayText' => 'x:ShippingMethod/@displayText', |
||
131 | 'fulfillmentChannel' => 'x:FulfillmentChannel', |
||
132 | 'estimatedDeliveryMode' => 'x:EstimatedDeliveryDate/x:Mode', |
||
133 | 'estimatedDeliveryMessageType' => 'x:EstimatedDeliveryDate/x:MessageType', |
||
134 | 'estimatedDeliveryTemplate' => 'x:EstimatedDeliveryDate/x:Template', |
||
135 | 'namedDeliveryMessage' => 'x:NamedDeliveryDate/x:Message', |
||
136 | 'deliveryInstructions' => 'x:DeliveryInstructions', |
||
137 | 'vendorId' => 'x:VendorId', |
||
138 | 'vendorName' => 'x:VendorName', |
||
139 | 'shopRunnerMessage' => 'x:ShopRunnerMessage', |
||
140 | 'giftItemId' => 'x:Gifting/x:Gift/x:ItemId', |
||
141 | 'giftMessageTo' => 'x:Gifting/x:Gift/x:Message/x:To', |
||
142 | 'giftMessageFrom' => 'x:Gifting/x:Gift/x:Message/x:From', |
||
143 | 'giftMessageContent' => 'x:Gifting/x:Gift/x:Message/x:Message', |
||
144 | 'giftCardTo' => 'x:Gifting/x:GiftCard/x:Message/x:To', |
||
145 | 'giftCardFrom' => 'x:Gifting/x:GiftCard/x:Message/x:From', |
||
146 | 'giftCardMessage' => 'x:Gifting/x:GiftCard/x:Message/x:Message', |
||
147 | 'packslipTo' => 'x:Gifting/x:Packslip/x:Message/x:To', |
||
148 | 'packslipFrom' => 'x:Gifting/x:Packslip/x:Message/x:From', |
||
149 | 'packslipMessage' => 'x:Gifting/x:Packslip/x:Message/x:Message', |
||
150 | 'localizedFromLabel' => 'x:Gifting/*/x:Message/x:From/@localizedDisplayText', |
||
151 | 'localizedToLabel' => 'x:Gifting/*/x:Message/x:To/@localizedDisplayText', |
||
152 | 'customizationDisplayUrl' => 'x:Customization/x:DisplayUrl', |
||
153 | 'serialNumber' => 'x:SerialNumber', |
||
154 | 'giftRegistryCancelUrl' => 'x:GiftRegistryCancelUrl', |
||
155 | 'reservationId' => 'x:ReservationId', |
||
156 | ]; |
||
157 | $this->subpayloadExtractionPaths = [ |
||
158 | 'fees' => 'x:Pricing/x:Fees', |
||
159 | 'customizations' => 'x:Customization/x:Customizations', |
||
160 | 'customAttributes' => 'x:CustomAttributes', |
||
161 | ]; |
||
162 | $this->booleanExtractionPaths = [ |
||
163 | 'isHiddenGift' => 'string(@isHiddenGift)', |
||
164 | ]; |
||
165 | |||
166 | $this->fees = $this->buildPayloadForInterface( |
||
167 | self::FEE_ITERABLE_INTERFACE |
||
168 | ); |
||
169 | $this->customizations = $this->buildPayloadForInterface( |
||
170 | self::CUSTOMIZATION_ITERABLE_INTERFACE |
||
171 | ); |
||
172 | $this->merchandisePricing = $this->buildPayloadForInterface( |
||
173 | self::PRICE_GROUP_INTERFACE |
||
174 | ); |
||
175 | $this->customAttributes = $this->buildPayloadForInterface( |
||
176 | self::CUSTOM_ATTRIBUTE_ITERABLE_INTERFACE |
||
177 | ); |
||
178 | } |
||
179 | |||
180 | public function getEmptyPriceGroup() |
||
184 | |||
185 | public function getEmptyStoreFrontDetails() |
||
189 | |||
190 | public function getEmptyProxyPickupDetails() |
||
194 | |||
195 | public function getLineNumber() |
||
199 | |||
200 | public function setLineNumber($lineNumber) |
||
201 | { |
||
202 | if ($lineNumber <= 999 && $lineNumber > 0) { |
||
203 | $this->lineNumber = $lineNumber; |
||
204 | } |
||
205 | return $this; |
||
206 | } |
||
207 | |||
208 | public function getIsHiddenGift() |
||
212 | |||
213 | public function setIsHiddenGift($isHiddenGift) |
||
214 | { |
||
215 | $this->isHiddenGift = (bool) $isHiddenGift; |
||
216 | return $this; |
||
217 | } |
||
218 | |||
219 | public function getTaxAndDutyDisplayType() |
||
223 | |||
224 | public function setTaxAndDutyDisplayType($taxAndDutyDisplayType) |
||
225 | { |
||
226 | $this->taxAndDutyDisplayType = $taxAndDutyDisplayType; |
||
227 | return $this; |
||
228 | } |
||
229 | |||
230 | public function getSubscriptionId() |
||
234 | |||
235 | public function setSubscriptionId($subscriptionId) |
||
236 | { |
||
237 | if ($subscriptionId <= 999 && $subscriptionId > 0) { |
||
238 | $this->subscriptionId = $subscriptionId; |
||
239 | } |
||
240 | return $this; |
||
241 | } |
||
242 | |||
243 | public function getItemId() |
||
247 | |||
248 | public function setItemId($itemId) |
||
249 | { |
||
250 | $this->itemId = $this->cleanString($itemId, 20); |
||
251 | return $this; |
||
252 | } |
||
253 | |||
254 | public function getQuantity() |
||
258 | |||
259 | public function setQuantity($quantity) |
||
260 | { |
||
261 | $this->quantity = $quantity; |
||
262 | return $this; |
||
263 | } |
||
264 | |||
265 | public function getScreenSize() |
||
269 | |||
270 | public function setScreenSize($screenSize) |
||
271 | { |
||
272 | $this->screenSize = $screenSize; |
||
273 | return $this; |
||
274 | } |
||
275 | |||
276 | public function getDepartment() |
||
280 | |||
281 | public function setDepartment($department) |
||
282 | { |
||
283 | $this->department = $department; |
||
284 | return $this; |
||
285 | } |
||
286 | |||
287 | public function getMerchandisePricing() |
||
291 | |||
292 | public function setMerchandisePricing(IPriceGroup $merchandisePricing) |
||
293 | { |
||
294 | $this->merchandisePricing = $merchandisePricing; |
||
295 | return $this; |
||
296 | } |
||
297 | |||
298 | public function getShippingPricing() |
||
302 | |||
303 | public function setShippingPricing(IPriceGroup $shippingPricing) |
||
304 | { |
||
305 | $this->shippingPricing = $shippingPricing; |
||
306 | return $this; |
||
307 | } |
||
308 | |||
309 | public function getDutyPricing() |
||
313 | |||
314 | public function setDutyPricing(IPriceGroup $dutyPricing) |
||
315 | { |
||
316 | $this->dutyPricing = $dutyPricing; |
||
317 | return $this; |
||
318 | } |
||
319 | |||
320 | public function getShippingProgram() |
||
324 | |||
325 | public function setShippingProgram($shippingProgram) |
||
326 | { |
||
327 | $this->shippingProgram = $shippingProgram; |
||
328 | return $this; |
||
329 | } |
||
330 | |||
331 | public function getShippingProgramAuthToken() |
||
335 | |||
336 | public function setShippingProgramAuthToken($shippingProgramAuthToken) |
||
337 | { |
||
338 | $this->shippingProgramAuthToken = $shippingProgramAuthToken; |
||
339 | return $this; |
||
340 | } |
||
341 | |||
342 | public function getShippingMethod() |
||
346 | |||
347 | public function setShippingMethod($shippingMethod) |
||
348 | { |
||
349 | $this->shippingMethod = $shippingMethod; |
||
350 | return $this; |
||
351 | } |
||
352 | |||
353 | public function getShippingMethodDisplayText() |
||
357 | |||
358 | public function setShippingMethodDisplayText($shippingMethodDisplayText) |
||
359 | { |
||
360 | $this->shippingMethodDisplayText = $shippingMethodDisplayText; |
||
361 | return $this; |
||
362 | } |
||
363 | |||
364 | public function getStoreFrontDetails() |
||
368 | |||
369 | public function setStoreFrontDetails(IStoreFrontDetails $storeFrontDetails) |
||
370 | { |
||
371 | $this->storeFrontDetails = $storeFrontDetails; |
||
372 | return $this; |
||
373 | } |
||
374 | |||
375 | public function getProxyPickupDetails() |
||
379 | |||
380 | public function setProxyPickupDetails(IProxyPickupDetails $proxyPickupDetails) |
||
381 | { |
||
382 | $this->proxyPickupDetails = $proxyPickupDetails; |
||
383 | return $this; |
||
384 | } |
||
385 | |||
386 | public function getFulfillmentChannel() |
||
390 | |||
391 | public function setFulfillmentChannel($fulfillmentChannel) |
||
392 | { |
||
393 | if ($fulfillmentChannel === self::FULFILLMENT_CHANNEL_SHIP_TO_STORE |
||
394 | || $fulfillmentChannel === self::FULFILLMENT_CHANNEL_STORE_PICK_UP |
||
395 | || $fulfillmentChannel === self::FULFILLMENT_CHANNEL_SHIP_TO_HOME |
||
396 | || $fulfillmentChannel === self::FULFILLMENT_CHANNEL_STORE_RESERVATION |
||
397 | ) { |
||
398 | $this->fulfillmentChannel = $fulfillmentChannel; |
||
399 | } |
||
400 | return $this; |
||
401 | } |
||
402 | |||
403 | public function getDeliveryInstructions() |
||
407 | |||
408 | public function setDeliveryInstructions($deliveryInstructions) |
||
409 | { |
||
410 | $this->deliveryInstructions = $this->normalizeWhitespace($deliveryInstructions); |
||
411 | return $this; |
||
412 | } |
||
413 | |||
414 | public function getVendorId() |
||
418 | |||
419 | public function setVendorId($vendorId) |
||
420 | { |
||
421 | $this->vendorId = $vendorId; |
||
422 | return $this; |
||
423 | } |
||
424 | |||
425 | public function getVendorName() |
||
429 | |||
430 | public function setVendorName($vendorName) |
||
431 | { |
||
432 | $this->vendorName = $vendorName; |
||
433 | return $this; |
||
434 | } |
||
435 | |||
436 | public function getShopRunnerMessage() |
||
440 | |||
441 | public function setShopRunnerMessage($shopRunnerMessage) |
||
442 | { |
||
443 | $this->shopRunnerMessage = $this->normalizeWhitespace($shopRunnerMessage); |
||
444 | return $this; |
||
445 | } |
||
446 | |||
447 | public function getSerialNumber() |
||
451 | |||
452 | public function setSerialNumber($serialNumber) |
||
453 | { |
||
454 | $this->serialNumber = $serialNumber; |
||
455 | return $this; |
||
456 | } |
||
457 | |||
458 | public function getGiftRegistryCancelUrl() |
||
462 | |||
463 | public function setGiftRegistryCancelUrl($giftRegistryCancelUrl) |
||
464 | { |
||
465 | $this->giftRegistryCancelUrl = $giftRegistryCancelUrl; |
||
466 | return $this; |
||
467 | } |
||
468 | |||
469 | public function getReservationId() |
||
473 | |||
474 | public function setReservationId($reservationId) |
||
475 | { |
||
476 | $this->reservationId = $this->cleanString($reservationId, 40); |
||
477 | return $this; |
||
478 | } |
||
479 | |||
480 | protected function serializeContents() |
||
481 | { |
||
482 | return "<ItemId>{$this->xmlEncode($this->getItemId())}</ItemId>" |
||
483 | . "<Quantity>{$this->getQuantity()}</Quantity>" |
||
484 | . $this->serializeDescription() |
||
485 | . $this->serializeOptionalXmlEncodedValue('Department', $this->getDepartment()) |
||
486 | . $this->serializePricing() |
||
487 | . $this->serializeShippingProgram() |
||
488 | . $this->serializeShippingMethod() |
||
489 | . $this->serializeOptionalSubpayload($this->getStoreFrontDetails()) |
||
490 | . $this->serializeOptionalXmlEncodedValue('FulfillmentChannel', $this->getFulfillmentChannel()) |
||
491 | . $this->serializeOptionalSubpayload($this->getProxyPickupDetails()) |
||
492 | . $this->serializeEstimatedDeliveryDate() |
||
493 | . $this->serializeNamedDeliveryDate() |
||
494 | . $this->serializeOptionalXmlEncodedValue('DeliveryInstructions', $this->getDeliveryInstructions()) |
||
495 | . $this->serializeOptionalXmlEncodedValue('VendorId', $this->getVendorId()) |
||
496 | . $this->serializeOptionalXmlEncodedValue('VendorName', $this->getVendorName()) |
||
497 | . $this->serializeGifting() |
||
498 | . $this->serializeOptionalXmlEncodedValue('ShopRunnerMessage', $this->getShopRunnerMessage()) |
||
499 | . $this->serializeCustomizations() |
||
500 | . $this->serializeOptionalXmlEncodedValue('SerialNumber', $this->getSerialNumber()) |
||
501 | . $this->getCustomAttributes()->serialize() |
||
502 | . $this->serializeOptionalXmlEncodedValue('GiftRegistryCancelUrl', $this->getGiftRegistryCancelUrl()) |
||
503 | . $this->serializeOptionalXmlEncodedValue('ReservationId', $this->getReservationId()); |
||
504 | } |
||
505 | |||
506 | /** |
||
507 | * Include an order item description only when the item has a description. |
||
508 | * |
||
509 | * @return string |
||
510 | */ |
||
511 | protected function serializeDescription() |
||
512 | { |
||
513 | if ($this->hasItemDescription()) { |
||
514 | return '<Description>' |
||
515 | . $this->serializeProductDescription() |
||
516 | . $this->serializeColor() |
||
517 | . $this->serializeSize() |
||
518 | . $this->serializeOptionalXmlEncodedValue('ScreenSize', $this->getScreenSize()) |
||
519 | . '</Description>'; |
||
520 | } |
||
521 | return ''; |
||
522 | } |
||
523 | |||
524 | /** |
||
525 | * Serialize order item pricing - merchandise pricing, shipping and duty |
||
526 | * pricing if they have been set and any fees for the item. |
||
527 | * |
||
528 | * @return string |
||
529 | */ |
||
530 | protected function serializePricing() |
||
531 | { |
||
532 | $shippingPricing = $this->getShippingPricing(); |
||
533 | $dutyPricing = $this->getDutyPricing(); |
||
534 | return '<Pricing>' |
||
535 | . $this->getMerchandisePricing()->setRootNodeName('Merchandise')->serialize() |
||
536 | . ($shippingPricing ? $shippingPricing->setRootNodeName('Shipping')->serialize() : '') |
||
537 | . ($dutyPricing ? $dutyPricing->setRootNodeName('Duty')->serialize() : '') |
||
538 | . $this->getFees()->serialize() |
||
539 | . '</Pricing>'; |
||
540 | } |
||
541 | |||
542 | /** |
||
543 | * Create a shipping program serialization if one is set for the payload. |
||
544 | * |
||
545 | * @return string |
||
546 | */ |
||
547 | View Code Duplication | protected function serializeShippingProgram() |
|
548 | { |
||
549 | if (!is_null($this->getShippingProgram())) { |
||
550 | return "<ShippingProgram {$this->serializeOptionalAttribute('authToken', $this->xmlEncode($this->getShippingProgramAuthToken()))}>" |
||
551 | . $this->xmlEncode($this->getShippingProgram()) |
||
552 | .'</ShippingProgram>'; |
||
553 | } |
||
554 | return ''; |
||
555 | } |
||
556 | |||
557 | /** |
||
558 | * Create a shipping method serialization if one is set for the payload. |
||
559 | * |
||
560 | * @return string |
||
561 | */ |
||
562 | View Code Duplication | protected function serializeShippingMethod() |
|
563 | { |
||
564 | if (!is_null($this->getShippingMethod())) { |
||
565 | return "<ShippingMethod {$this->serializeOptionalAttribute('displayText', $this->xmlEncode($this->getShippingMethodDisplayText()))}>" |
||
566 | . $this->xmlEncode($this->getShippingMethod()) |
||
567 | .'</ShippingMethod>'; |
||
568 | } |
||
569 | return ''; |
||
570 | } |
||
571 | |||
572 | /** |
||
573 | * If given an IPayload, return the serialization of the payload. Otherwise, |
||
574 | * return an empty string, no serialization. |
||
575 | * |
||
576 | * @param IPayload |
||
577 | * @return string |
||
578 | */ |
||
579 | protected function serializeOptionalSubpayload(IPayload $payload = null) |
||
583 | |||
584 | protected function deserializeExtra($serializePayload) |
||
585 | { |
||
586 | $xpath = $this->getPayloadAsXPath($serializePayload); |
||
587 | return $this->deserializeDateTimes($xpath) |
||
588 | ->deserializeItemPrices($xpath) |
||
589 | ->deserializeStoreFrontLocation($xpath) |
||
590 | ->deserializeProxyPickupDetails($xpath) |
||
591 | ->deserializeGiftPricing($xpath) |
||
592 | ->deserializeCustomizationBasePrice($xpath); |
||
593 | } |
||
594 | |||
595 | /** |
||
596 | * Deserialize date time objects from the serialized payload in the DOMXPath. |
||
597 | * |
||
598 | * @param DOMXPath |
||
599 | * @return self |
||
600 | */ |
||
601 | protected function deserializeDateTimes(DOMXPath $xpath) |
||
602 | { |
||
603 | $dateProperties = [ |
||
604 | 'estimatedDeliveryWindowFrom' => 'string(x:EstimatedDeliveryDate/x:DeliveryWindow/x:From)', |
||
605 | 'estimatedDeliveryWindowTo' => 'string(x:EstimatedDeliveryDate/x:DeliveryWindow/x:To)', |
||
606 | 'estimatedShippingWindowFrom' => 'string(x:EstimatedDeliveryDate/x:ShippingWindow/x:From)', |
||
607 | 'estimatedShippingWindowTo' => 'string(x:EstimatedDeliveryDate/x:ShippingWindow/x:To)', |
||
608 | 'namedDeliveryDate' => 'string(x:NamedDeliveryDate/x:DeliveryDate)', |
||
609 | 'namedDeliveryTimeWindowStart' => 'string(x:NamedDeliveryDate/x:TimeWindowStart)', |
||
610 | 'namedDeliveryTimeWindowEnd' => 'string(x:NamedDeliveryDate/x:TimeWindowEnd)', |
||
611 | ]; |
||
612 | View Code Duplication | foreach ($dateProperties as $prop => $extractPath) { |
|
613 | $value = $xpath->evaluate($extractPath); |
||
614 | $this->$prop = $value ? new DateTime($value) : null; |
||
615 | } |
||
616 | return $this; |
||
617 | } |
||
618 | |||
619 | /** |
||
620 | * Deserialize store front location if one is included in the serialization. |
||
621 | * |
||
622 | * @param DOMXPath |
||
623 | * @return self |
||
624 | */ |
||
625 | protected function deserializeStoreFrontLocation(DOMXPath $xpath) |
||
626 | { |
||
627 | $detailsNode = $xpath->query('x:StoreFrontDetails')->item(0); |
||
628 | if ($detailsNode) { |
||
629 | $this->setStoreFrontDetails( |
||
630 | $this->getEmptyStoreFrontDetails()->deserialize($detailsNode->C14N()) |
||
631 | ); |
||
632 | } |
||
633 | return $this; |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * Deserialize proxy pickup details if one is included in the serialization. |
||
638 | * |
||
639 | * @param DOMXPath |
||
640 | * @return self |
||
641 | */ |
||
642 | protected function deserializeProxyPickupDetails(DOMXPath $xpath) |
||
643 | { |
||
644 | $detailsNode = $xpath->query('x:ProxyPickupDetails')->item(0); |
||
645 | if ($detailsNode) { |
||
646 | $this->setProxyPickupDetails( |
||
647 | $this->getEmptyProxyPickupDetails()->deserialize($detailsNode->C14N()) |
||
648 | ); |
||
649 | } |
||
650 | return $this; |
||
651 | } |
||
652 | |||
653 | /** |
||
654 | * Deserialize price groups from the serialized payload in the DOMXPath. |
||
655 | * |
||
656 | * @param DOMXPath |
||
657 | * @return self |
||
658 | */ |
||
659 | protected function deserializeItemPrices(DOMXPath $xpath) |
||
660 | { |
||
661 | $itemPrices = [ |
||
662 | 'merchandisePricing' => 'x:Pricing/x:Merchandise', |
||
663 | 'shippingPricing' => 'x:Pricing/x:Shipping', |
||
664 | 'dutyPricing' => 'x:Pricing/x:Duty', |
||
665 | ]; |
||
666 | foreach ($itemPrices as $property => $extractionPath) { |
||
667 | $priceNode = $xpath->query($extractionPath)->item(0); |
||
668 | if ($priceNode) { |
||
669 | $this->$property = $this->getEmptyPriceGroup()->deserialize($priceNode->C14N()); |
||
670 | } |
||
671 | } |
||
672 | return $this; |
||
673 | } |
||
674 | |||
675 | protected function getRootAttributes() |
||
676 | { |
||
677 | $isHiddenGift = $this->getIsHiddenGift(); |
||
678 | return array_filter([ |
||
679 | 'id' => $this->getId(), |
||
680 | 'webLineId' => $this->getLineNumber(), |
||
681 | 'isHiddenGift' => !is_null($isHiddenGift) ? $this->convertBooleanToString($isHiddenGift) : null, |
||
682 | 'taxAndDutyDisplay' => $this->getTaxAndDutyDisplayType(), |
||
683 | 'subscriptionId' => $this->getSubscriptionId(), |
||
684 | ]); |
||
685 | } |
||
686 | |||
687 | protected function getRootNodeName() |
||
691 | |||
692 | protected function getXmlNamespace() |
||
696 | } |
||
697 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..