![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-shipping/Model/Carrier/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Shipping\Model\Carrier; use Magento\Framework\Exception\LocalizedException; use Magento\Quote\Model\Quote\Address\RateRequest; use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Shipping\Model\Shipment\Request; use Magento\Framework\Xml\Security; /** * Abstract online shipping carrier model * * phpcs:disable Magento2.Classes.AbstractApi * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ abstract class AbstractCarrierOnline extends AbstractCarrier { public const USA_COUNTRY_ID = 'US'; public const PUERTORICO_COUNTRY_ID = 'PR'; public const GUAM_COUNTRY_ID = 'GU'; public const GUAM_REGION_CODE = 'GU'; /** * @var array */ protected static $_quotesCache = []; /** * @var string */ protected $_activeFlag = 'active'; /** * @var \Magento\Directory\Helper\Data */ protected $_directoryData = null; /** * @var \Magento\Shipping\Model\Simplexml\ElementFactory */ protected $_xmlElFactory; /** * @var \Magento\Shipping\Model\Rate\ResultFactory */ protected $_rateFactory; /** * @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory */ protected $_rateMethodFactory; /** * @var \Magento\Shipping\Model\Tracking\ResultFactory */ protected $_trackFactory; /** * @var \Magento\Shipping\Model\Tracking\Result\ErrorFactory */ protected $_trackErrorFactory; /** * @var \Magento\Shipping\Model\Tracking\Result\StatusFactory */ protected $_trackStatusFactory; /** * @var \Magento\Directory\Model\RegionFactory */ protected $_regionFactory; /** * @var \Magento\Directory\Model\CountryFactory */ protected $_countryFactory; /** * @var \Magento\Directory\Model\CurrencyFactory */ protected $_currencyFactory; /** * @var \Magento\CatalogInventory\Api\StockRegistryInterface */ protected $stockRegistry; /** * Raw rate request data * * @var \Magento\Framework\DataObject|null */ protected $_rawRequest = null; /** * @var Security */ protected $xmlSecurity; /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory * @param \Psr\Log\LoggerInterface $logger * @param Security $xmlSecurity * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory * @param \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory * @param \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory * @param \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory * @param \Magento\Directory\Model\RegionFactory $regionFactory * @param \Magento\Directory\Model\CountryFactory $countryFactory * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory * @param \Magento\Directory\Helper\Data $directoryData * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory, \Psr\Log\LoggerInterface $logger, Security $xmlSecurity, \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory, \Magento\Shipping\Model\Rate\ResultFactory $rateFactory, \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory, \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory, \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory, \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory, \Magento\Directory\Model\RegionFactory $regionFactory, \Magento\Directory\Model\CountryFactory $countryFactory, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Directory\Helper\Data $directoryData, \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry, array $data = [] ) { $this->_xmlElFactory = $xmlElFactory; $this->_rateFactory = $rateFactory; $this->_rateMethodFactory = $rateMethodFactory; $this->_trackFactory = $trackFactory; $this->_trackErrorFactory = $trackErrorFactory; $this->_trackStatusFactory = $trackStatusFactory; $this->_regionFactory = $regionFactory; $this->_countryFactory = $countryFactory; $this->_currencyFactory = $currencyFactory; $this->_directoryData = $directoryData; $this->stockRegistry = $stockRegistry; parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data); $this->xmlSecurity = $xmlSecurity; } /** * Set flag for check carriers for activity * * @param string $code * @return $this */ public function setActiveFlag($code = 'active') { $this->_activeFlag = $code; return $this; } /** * Return code of carrier * * @return string|null */ public function getCarrierCode() { return $this->_code ?? null; } /** * Get tracking information * * @param string $tracking * @return string|false */ public function getTrackingInfo($tracking) { $result = $this->getTracking($tracking); if ($result instanceof \Magento\Shipping\Model\Tracking\Result) { $trackings = $result->getAllTrackings(); if ($trackings) { return $trackings[0]; } } elseif (is_string($result) && !empty($result)) { return $result; } return false; } /** * Check if carrier has shipping tracking option available * * All \Magento\Usa carriers have shipping tracking option available * * @return boolean */ public function isTrackingAvailable() { return true; } /** * Check if city option required * * @return boolean */ public function isCityRequired() { return true; } /** * Determine whether zip-code is required for the country of destination * * @param string|null $countryId * @return bool */ public function isZipCodeRequired($countryId = null) { if ($countryId != null) { return !$this->_directoryData->isZipCodeOptional($countryId); } return true; } /** * Check if carrier has shipping label option available * * @return boolean */ public function isShippingLabelsAvailable() { return true; } /** * Return items for further shipment rate evaluation. We need to pass children of a bundle instead passing the * bundle itself, otherwise we may not get a rate at all (e.g. when total weight of a bundle exceeds max weight * despite each item by itself is not) * * @param RateRequest $request * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function getAllItems(RateRequest $request) { $items = []; if ($request->getAllItems()) { foreach ($request->getAllItems() as $item) { /* @var $item \Magento\Quote\Model\Quote\Item */ if ($item->getProduct()->isVirtual() || $item->getParentItem()) { // Don't process children here - we will process (or already have processed) them below continue; } if ($item->getHasChildren() && $item->isShipSeparately()) { foreach ($item->getChildren() as $child) { if (!$child->getFreeShipping() && !$child->getProduct()->isVirtual()) { $items[] = $child; } } } else { // Ship together - count compound item as one solid $items[] = $item; } } } return $items; } /** * Processing additional validation to check if carrier applicable. * * @param \Magento\Framework\DataObject $request * @return $this|bool|\Magento\Framework\DataObject * @deprecated 100.2.6 * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function proccessAdditionalValidation(\Magento\Framework\DataObject $request) { return $this->processAdditionalValidation($request); } /** * Processing additional validation to check if carrier applicable. * * @param \Magento\Framework\DataObject $request * @return $this|bool|\Magento\Framework\DataObject * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @since 100.2.6 */ public function processAdditionalValidation(\Magento\Framework\DataObject $request) { //Skip by item validation if there is no items in request if (!count($this->getAllItems($request))) { return $this; } $maxAllowedWeight = (double)$this->getConfigData('max_package_weight'); $errorMsg = ''; $configErrorMsg = $this->getConfigData('specificerrmsg'); $defaultErrorMsg = __('The shipping module is not available.'); $showMethod = $this->getConfigData('showmethod'); /** @var $item \Magento\Quote\Model\Quote\Item */ foreach ($this->getAllItems($request) as $item) { $product = $item->getProduct(); if ($product && $product->getId()) { $weight = $product->getWeight(); $stockItemData = $this->stockRegistry->getStockItem( $product->getId(), $item->getStore()->getWebsiteId() ); $doValidation = true; if ($stockItemData->getIsQtyDecimal() && $stockItemData->getIsDecimalDivided()) { if ($stockItemData->getEnableQtyIncrements() && $stockItemData->getQtyIncrements() ) { $weight = $weight * $stockItemData->getQtyIncrements(); } else { $doValidation = false; } } elseif ($stockItemData->getIsQtyDecimal() && !$stockItemData->getIsDecimalDivided()) { $weight = $weight * $item->getQty(); } if ($doValidation && $weight > $maxAllowedWeight) { $errorMsg = $configErrorMsg ? $configErrorMsg : $defaultErrorMsg; break; } } } if (!$errorMsg && !$request->getDestPostcode() && $this->isZipCodeRequired($request->getDestCountryId())) { $errorMsg = __('This shipping method is not available. Please specify the zip code.'); } if ($errorMsg && $showMethod) { $error = $this->_rateErrorFactory->create(); $error->setCarrier($this->_code); $error->setCarrierTitle($this->getConfigData('title')); $error->setErrorMessage($errorMsg); return $error; } elseif ($errorMsg) { return false; } return $this; } /** * Returns cache key for some request to carrier quotes service * * @param string|array $requestParams * @return string */ protected function _getQuotesCacheKey($requestParams) { if (is_array($requestParams)) { $requestParams = implode( ',', array_merge([$this->getCarrierCode()], array_keys($requestParams), $requestParams) ); } return crc32($requestParams); } /** * Checks whether some request to rates have already been done, so we have cache for it * * Used to reduce number of same requests done to carrier service during one session * Returns cached response or null * * @param string|array $requestParams * @return null|string */ protected function _getCachedQuotes($requestParams) { $key = $this->_getQuotesCacheKey($requestParams); return self::$_quotesCache[$key] ?? null; } /** * Sets received carrier quotes to cache * * @param string|array $requestParams * @param string $response * @return $this */ protected function _setCachedQuotes($requestParams, $response) { $key = $this->_getQuotesCacheKey($requestParams); self::$_quotesCache[$key] = $response; return $this; } /** * Prepare service name. Strip tags and entities from name * * @param string|object $name service name or object with implemented __toString() method * @return string prepared service name */ protected function _prepareServiceName($name) { // phpcs:ignore Magento2.Functions.DiscouragedFunction $name = html_entity_decode((string)$name); $name = strip_tags(preg_replace('#&\w+;#', '', $name)); return trim($name); } /** * Prepare shipment request. Validate and correct request information * * @param \Magento\Framework\DataObject $request * @return void */ protected function _prepareShipmentRequest(\Magento\Framework\DataObject $request) { $phonePattern = '/[\s\_\-\(\)]+/'; $phoneNumber = $request->getShipperContactPhoneNumber(); $phoneNumber = is_string($phoneNumber) ? preg_replace($phonePattern, '', $phoneNumber) : ''; $request->setShipperContactPhoneNumber($phoneNumber); $phoneNumber = $request->getRecipientContactPhoneNumber(); $phoneNumber = is_string($phoneNumber) ? preg_replace($phonePattern, '', $phoneNumber) : ''; $request->setRecipientContactPhoneNumber($phoneNumber); } /** * Do request to shipment * * @param Request $request * @return \Magento\Framework\DataObject * @throws \Magento\Framework\Exception\LocalizedException */ public function requestToShipment($request) { $packages = $request->getPackages(); if (!is_array($packages) || !$packages) { throw new LocalizedException(__('No packages for request')); } if ($request->getStoreId() != null) { $this->setStore($request->getStoreId()); } $data = []; foreach ($packages as $packageId => $package) { $request->setPackageId($packageId); $request->setPackagingType($package['params']['container']); $request->setPackageWeight($package['params']['weight']); $request->setPackageParams(new \Magento\Framework\DataObject($package['params'])); $request->setPackageItems($package['items']); $result = $this->_doShipmentRequest($request); if ($result->hasErrors()) { $this->rollBack($data); break; } else { $data[] = [ 'tracking_number' => $result->getTrackingNumber(), 'label_content' => $result->getShippingLabelContent(), ]; } if (!isset($isFirstRequest)) { $request->setMasterTrackingId($result->getTrackingNumber()); $isFirstRequest = false; } } $response = new \Magento\Framework\DataObject(['info' => $data]); if ($result->getErrors()) { $response->setErrors($result->getErrors()); } return $response; } /** * Do request to RMA shipment * * @param Request $request * @return \Magento\Framework\DataObject * @throws \Magento\Framework\Exception\LocalizedException */ public function returnOfShipment($request) { $request->setIsReturn(true); $packages = $request->getPackages(); if (!is_array($packages) || !$packages) { throw new LocalizedException(__('No packages for request')); } if ($request->getStoreId() != null) { $this->setStore($request->getStoreId()); } $data = []; foreach ($packages as $packageId => $package) { $request->setPackageId($packageId); $request->setPackagingType($package['params']['container']); $request->setPackageWeight($package['params']['weight']); $request->setPackageParams(new \Magento\Framework\DataObject($package['params'])); $request->setPackageItems($package['items']); $result = $this->_doShipmentRequest($request); if ($result->hasErrors()) { $this->rollBack($data); break; } else { $data[] = [ 'tracking_number' => $result->getTrackingNumber(), 'label_content' => $result->getShippingLabelContent(), ]; } if (!isset($isFirstRequest)) { $request->setMasterTrackingId($result->getTrackingNumber()); $isFirstRequest = false; } } $response = new \Magento\Framework\DataObject(['info' => $data]); if ($result->getErrors()) { $response->setErrors($result->getErrors()); } return $response; } /** * For multi package shipments. Delete requested shipments if the current shipment. Request is failed * * @param array $data * @return bool * * @todo implement rollback logic * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function rollBack($data) { return true; } /** * Do shipment request to carrier web service, obtain Print Shipping Labels and process errors in response * * @param \Magento\Framework\DataObject $request * @return \Magento\Framework\DataObject */ abstract protected function _doShipmentRequest(\Magento\Framework\DataObject $request); /** * Check is Country U.S. Possessions and Trust Territories * * @param string $countyId * @return boolean */ protected function _isUSCountry($countyId) { switch ($countyId) { case 'AS': // Samoa American case 'GU': // Guam case 'MP': // Northern Mariana Islands case 'PW': // Palau case 'PR': // Puerto Rico case 'VI': // Virgin Islands US case 'US': // United States return true; } return false; } /** * Check whether girth is allowed for the carrier * * @param null|string $countyDest * @param null|string $carrierMethodCode * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function isGirthAllowed($countyDest = null, $carrierMethodCode = null) { return false; } /** * Set Raw Request * * @param \Magento\Framework\DataObject|null $request * @return $this */ public function setRawRequest($request) { $this->_rawRequest = $request; return $this; } /** * Calculate price considering free shipping and handling fee * * @param string $cost * @param string $method * @return float|string */ public function getMethodPrice($cost, $method = '') { return $method == $this->getConfigData( $this->_freeMethod ) && $this->getConfigFlag( 'free_shipping_enable' ) && $this->getConfigData( 'free_shipping_subtotal' ) <= $this->_rawRequest->getValueWithDiscount() ? '0.00' : $this->getFinalPriceWithHandlingFee( $cost ); } /** * Parse XML string and return XML document object or false * * @param string $xmlContent * @param string $customSimplexml * @return \SimpleXMLElement|bool * @throws LocalizedException */ public function parseXml($xmlContent, $customSimplexml = 'SimpleXMLElement') { if (!$this->xmlSecurity->scan($xmlContent)) { throw new LocalizedException(__('The security validation of the XML document has failed.')); } $xmlElement = simplexml_load_string($xmlContent, $customSimplexml); return $xmlElement; } /** * Checks if shipping method can collect rates * * @return bool */ public function canCollectRates() { return (bool)$this->getConfigFlag($this->_activeFlag); } /** * Debug errors if showmethod is unset * * @param Error $errors * * @return void */ protected function debugErrors($errors) { if ($this->getConfigData('showmethod')) { /* @var $error Error */ $this->_debug($errors); } } /** * Get error messages * * @return bool|Error */ protected function getErrorMessage() { if ($this->getConfigData('showmethod')) { /* @var $error Error */ $error = $this->_rateErrorFactory->create(); $error->setCarrier($this->getCarrierCode()); $error->setCarrierTitle($this->getConfigData('title')); $error->setErrorMessage($this->getConfigData('specificerrmsg')); return $error; } else { return false; } } }