/
home
/
sharedstore
/
public_html
/
prestashop.sharedstore.ma
/
classes
/
/home/sharedstore/public_html/prestashop.sharedstore.ma/classes
mkdir
upload
Name
Size
Mode
Actions
assets/
-
0755
rm
cache/
-
0755
rm
checkout/
-
0755
rm
container/
-
0755
rm
controller/
-
0755
rm
db/
-
0755
rm
exception/
-
0755
rm
form/
-
0755
rm
helper/
-
0755
rm
lang/
-
0755
rm
log/
-
0755
rm
module/
-
0755
rm
order/
-
0755
rm
pdf/
-
0755
rm
product/
-
0755
rm
proxy/
-
0755
rm
range/
-
0755
rm
shop/
-
0755
rm
Smarty/
-
0755
rm
stock/
-
0755
rm
tax/
-
0755
rm
tree/
-
0755
rm
webservice/
-
0755
rm
.htaccess
170
0644
edit
dl
rm
Access.php
13573
0644
edit
dl
rm
Address.php
23016
0644
edit
dl
rm
AddressChecksumCore.php
1851
0644
edit
dl
rm
AddressFormat.php
25125
0644
edit
dl
rm
Alias.php
5106
0644
edit
dl
rm
Attachment.php
11557
0644
edit
dl
rm
AttributeGroup.php
13488
0644
edit
dl
rm
Carrier.php
65666
0644
edit
dl
rm
Cart.php
221192
0644
edit
dl
rm
CartRule.php
92765
0644
edit
dl
rm
Category.php
89171
0644
edit
dl
rm
Chart.php
4177
0644
edit
dl
rm
ChecksumInterface.php
1246
0644
edit
dl
rm
CMS.php
11725
0644
edit
dl
rm
CMSCategory.php
24148
0644
edit
dl
rm
CMSRole.php
1822
0644
edit
dl
rm
Combination.php
18012
0644
edit
dl
rm
Configuration.php
27156
0644
edit
dl
rm
ConfigurationKPI.php
9126
0644
edit
dl
rm
ConfigurationTest.php
12309
0644
edit
dl
rm
Connection.php
10262
0644
edit
dl
rm
ConnectionsSource.php
4926
0644
edit
dl
rm
Contact.php
3954
0644
edit
dl
rm
Context.php
18372
0644
edit
dl
rm
Cookie.php
17806
0644
edit
dl
rm
Country.php
16723
0644
edit
dl
rm
CSV.php
3110
0644
edit
dl
rm
Currency.php
37167
0644
edit
dl
rm
Curve.php
2993
0644
edit
dl
rm
Customer.php
53576
0644
edit
dl
rm
CustomerAddress.php
1295
0644
edit
dl
rm
CustomerMessage.php
5890
0644
edit
dl
rm
CustomerSession.php
2718
0644
edit
dl
rm
CustomerThread.php
9848
0644
edit
dl
rm
Customization.php
13754
0644
edit
dl
rm
CustomizationField.php
2915
0644
edit
dl
rm
DateRange.php
2532
0644
edit
dl
rm
Delivery.php
3317
0644
edit
dl
rm
Dispatcher.php
48810
0644
edit
dl
rm
Employee.php
24062
0644
edit
dl
rm
EmployeeSession.php
2718
0644
edit
dl
rm
Feature.php
11656
0644
edit
dl
rm
FeatureFlag.php
3226
0644
edit
dl
rm
FeatureValue.php
8249
0644
edit
dl
rm
FileUploader.php
3820
0644
edit
dl
rm
Gender.php
2876
0644
edit
dl
rm
Group.php
15323
0644
edit
dl
rm
GroupReduction.php
9025
0644
edit
dl
rm
Guest.php
8529
0644
edit
dl
rm
Hook.php
50909
0644
edit
dl
rm
Image.php
32418
0644
edit
dl
rm
ImageManager.php
32549
0644
edit
dl
rm
ImageType.php
7155
0644
edit
dl
rm
index.php
1372
0644
edit
dl
rm
Language.php
63547
0644
edit
dl
rm
Link.php
63814
0644
edit
dl
rm
LocalizationPack.php
23604
0644
edit
dl
rm
Mail.php
34312
0644
edit
dl
rm
Manufacturer.php
21745
0644
edit
dl
rm
ManufacturerAddress.php
1311
0644
edit
dl
rm
Media.php
33021
0644
edit
dl
rm
Message.php
6626
0644
edit
dl
rm
Meta.php
18577
0644
edit
dl
rm
Notification.php
8470
0644
edit
dl
rm
ObjectModel.php
83773
0644
edit
dl
rm
Pack.php
26332
0644
edit
dl
rm
Page.php
4598
0644
edit
dl
rm
PaymentFree.php
1362
0644
edit
dl
rm
PaymentModule.php
61197
0644
edit
dl
rm
PhpEncryption.php
3291
0644
edit
dl
rm
PhpEncryptionEngine.php
3949
0644
edit
dl
rm
PrestaShopAutoload.php
9799
0644
edit
dl
rm
PrestaShopBackup.php
11702
0644
edit
dl
rm
PrestaShopCollection.php
21790
0644
edit
dl
rm
PrestaShopLogger.php
8523
0644
edit
dl
rm
Product.php
318056
0644
edit
dl
rm
ProductAssembler.php
6895
0644
edit
dl
rm
ProductAttribute.php
13808
0644
edit
dl
rm
ProductDownload.php
10294
0644
edit
dl
rm
ProductPresenterFactory.php
3983
0644
edit
dl
rm
ProductSale.php
13000
0644
edit
dl
rm
ProductSupplier.php
8537
0644
edit
dl
rm
Profile.php
8523
0644
edit
dl
rm
QqUploadedFileForm.php
5317
0644
edit
dl
rm
QqUploadedFileXhr.php
5825
0644
edit
dl
rm
QuickAccess.php
6402
0644
edit
dl
rm
RequestSql.php
21453
0644
edit
dl
rm
Risk.php
2419
0644
edit
dl
rm
Search.php
59229
0644
edit
dl
rm
SearchEngine.php
2879
0644
edit
dl
rm
SpecificPrice.php
33212
0644
edit
dl
rm
SpecificPriceRule.php
14374
0644
edit
dl
rm
State.php
7956
0644
edit
dl
rm
Store.php
6394
0644
edit
dl
rm
Supplier.php
18339
0644
edit
dl
rm
SupplierAddress.php
1299
0644
edit
dl
rm
Tab.php
22223
0644
edit
dl
rm
Tag.php
13558
0644
edit
dl
rm
Tools.php
140903
0644
edit
dl
rm
Translate.php
12059
0644
edit
dl
rm
TranslatedConfiguration.php
4792
0644
edit
dl
rm
Upgrader.php
11859
0644
edit
dl
rm
Uploader.php
11104
0644
edit
dl
rm
Validate.php
39801
0644
edit
dl
rm
ValidateConstraintTranslator.php
2611
0644
edit
dl
rm
WarehouseAddress.php
1302
0644
edit
dl
rm
Zone.php
3500
0644
edit
dl
rm
Edit:
/home/sharedstore/public_html/prestashop.sharedstore.ma/classes/Carrier.php
(65666B)
<?php /** * Copyright since 2007 PrestaShop SA and Contributors * PrestaShop is an International Registered Trademark & Property of PrestaShop SA * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.md. * It is also available through the world-wide-web at this URL: * https://opensource.org/licenses/OSL-3.0 * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@prestashop.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade PrestaShop to newer * versions in the future. If you wish to customize PrestaShop for your * needs please refer to https://devdocs.prestashop.com/ for more information. * * @author PrestaShop SA and Contributors <contact@prestashop.com> * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ use PrestaShop\PrestaShop\Adapter\ServiceLocator; class CarrierCore extends ObjectModel { /** * getCarriers method filter. */ public const PS_CARRIERS_ONLY = 1; public const CARRIERS_MODULE = 2; public const CARRIERS_MODULE_NEED_RANGE = 3; public const PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE = 4; public const ALL_CARRIERS = 5; public const SHIPPING_METHOD_DEFAULT = 0; public const SHIPPING_METHOD_WEIGHT = 1; public const SHIPPING_METHOD_PRICE = 2; public const SHIPPING_METHOD_FREE = 3; public const SHIPPING_PRICE_EXCEPTION = 0; public const SHIPPING_WEIGHT_EXCEPTION = 1; public const SHIPPING_SIZE_EXCEPTION = 2; public const SORT_BY_PRICE = 0; public const SORT_BY_POSITION = 1; public const SORT_BY_ASC = 0; public const SORT_BY_DESC = 1; /** @var int common id for carrier historization */ public $id_reference; /** @var string Name */ public $name; /** @var string URL with a '@' for */ public $url; /** @var string Delay needed to deliver customer */ public $delay; /** @var bool Carrier statuts */ public $active = true; /** @var bool True if carrier has been deleted (staying in database as deleted) */ public $deleted = false; /** @var bool True if extra shipping handling cost should be applied to this Carrier */ public $shipping_handling = true; /** @var bool Behavior for out-of-range weights: true to disable carrier, false to apply the cost of the highest defined range */ public $range_behavior; /** @var bool Carrier module */ public $is_module; /** @var bool Free carrier */ public $is_free = false; /** @var int Shipping cost calculation method: by weight or by price or free */ public $shipping_method = 0; /** * @var bool True if external module calculates shipping cost * * @see Cart::getPackageShippingCostFromModule() */ public $shipping_external = false; /** @var string Name of external module responsible for this Carrier */ public $external_module_name = null; /** * @var bool True if module needs core range-based shipping cost to calculate final cost * * @see Cart::getPackageShippingCostFromModule() */ public $need_range = false; /** @var int Position */ public $position; /** @var int maximum package width managed by the transporter */ public $max_width; /** @var int maximum package height managed by the transporter */ public $max_height; /** @var int maximum package deep managed by the transporter */ public $max_depth; /** @var int maximum package weight managed by the transporter */ public $max_weight; /** @var int grade of the shipping delay (0 for longest, 9 for shortest) */ public $grade; /** * @see ObjectModel::$definition */ public static $definition = [ 'table' => 'carrier', 'primary' => 'id_carrier', 'multilang' => true, 'multilang_shop' => true, 'fields' => [ /* Classic fields */ 'id_reference' => ['type' => self::TYPE_INT], 'name' => ['type' => self::TYPE_STRING, 'validate' => 'isCarrierName', 'required' => true, 'size' => 64], 'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true], 'is_free' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'url' => ['type' => self::TYPE_STRING, 'validate' => 'isAbsoluteUrl'], 'shipping_handling' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'shipping_external' => ['type' => self::TYPE_BOOL], 'range_behavior' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'shipping_method' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'], 'max_width' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'], 'max_height' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'], 'max_depth' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'], 'max_weight' => ['type' => self::TYPE_FLOAT, 'validate' => 'isFloat'], 'grade' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'size' => 1], 'external_module_name' => ['type' => self::TYPE_STRING, 'size' => 64], 'is_module' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'need_range' => ['type' => self::TYPE_BOOL], 'position' => ['type' => self::TYPE_INT], 'deleted' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], /* Lang fields */ 'delay' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 512], ], ]; protected static $price_by_weight = []; protected static $price_by_weight2 = []; protected static $price_by_price = []; protected static $price_by_price2 = []; protected static $cache_tax_rule = []; protected $webserviceParameters = [ 'fields' => [ 'deleted' => [], 'is_module' => [], 'id_tax_rules_group' => [ 'getter' => 'getIdTaxRulesGroup', 'setter' => 'setTaxRulesGroup', 'xlink_resource' => [ 'resourceName' => 'tax_rule_groups', ], ], ], ]; /** * CarrierCore constructor. * * @param int|null $id Carrier ID * @param int|null $id_lang Language ID */ public function __construct($id = null, $id_lang = null) { parent::__construct($id, $id_lang); $this->image_dir = _PS_SHIP_IMG_DIR_; /* * keep retrocompatibility SHIPPING_METHOD_DEFAULT */ if ($this->shipping_method == Carrier::SHIPPING_METHOD_DEFAULT) { $this->shipping_method = ((int) Configuration::get('PS_SHIPPING_METHOD') ? Carrier::SHIPPING_METHOD_WEIGHT : Carrier::SHIPPING_METHOD_PRICE); } } public static function resetStaticCache() { static::$price_by_weight = []; static::$price_by_weight2 = []; static::$price_by_price = []; static::$price_by_price2 = []; static::$cache_tax_rule = []; Cache::clean('Carrier::*'); } /** * Adds current Carrier as a new Object to the database. * * @param bool $autoDate Automatically set `date_upd` and `date_add` columns * @param bool $nullValues Whether we want to use NULL values instead of empty quotes values * * @return bool Whether the Carrier has been successfully added * * @throws PrestaShopDatabaseException * @throws PrestaShopException */ public function add($autoDate = true, $nullValues = false) { if ($this->position <= 0) { $this->position = Carrier::getHigherPosition() + 1; } if (!parent::add($autoDate, $nullValues) || !Validate::isLoadedObject($this)) { return false; } if (!$count = Db::getInstance()->getValue('SELECT count(`id_carrier`) FROM `' . _DB_PREFIX_ . $this->def['table'] . '` WHERE `deleted` = 0')) { return false; } if ($count == 1) { Configuration::updateValue('PS_CARRIER_DEFAULT', (int) $this->id); } // Register reference Db::getInstance()->execute( 'UPDATE `' . _DB_PREFIX_ . $this->def['table'] . '` SET `id_reference` = ' . (int) $this->id . ' WHERE `id_carrier` = ' . (int) $this->id ); foreach (Shop::getContextListShopID() as $shopId) { foreach (Module::getPaymentModules() as $module) { Db::getInstance()->execute( ' INSERT INTO `' . _DB_PREFIX_ . 'module_' . bqSQL('carrier') . '` (`id_module`, `id_shop`, `id_' . bqSQL('reference') . '`) VALUES (' . (int) $module['id_module'] . ',' . (int) $shopId . ',' . (int) $this->id . ')' ); } } return true; } /** * @since 1.5.0 * @see ObjectModel::delete() */ public function delete() { if ($this->isUsed()) { return parent::softDelete() && Carrier::cleanPositions(); } else { if (!parent::delete()) { return false; } Carrier::cleanPositions(); return Db::getInstance()->delete('cart_rule_carrier', 'id_carrier = ' . (int) $this->id) && Db::getInstance()->delete('module_carrier', 'id_reference = ' . (int) $this->id_reference) && $this->deleteTaxRulesGroup(Shop::getShops(true, null, true)); } } /** * Change carrier id in delivery prices when updating a carrier. * * @param int $id_old Old Carrier ID */ public function setConfiguration($id_old) { Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'delivery` SET `id_carrier` = ' . (int) $this->id . ' WHERE `id_carrier` = ' . (int) $id_old); } /** * Get delivery price for a given order. * * @param float $total_weight Total order weight * @param int $id_zone Zone ID (for customer delivery address) * * @return float|bool Delivery price, false if not possible */ public function getDeliveryPriceByWeight($total_weight, $id_zone) { $id_carrier = (int) $this->id; $cache_key = $id_carrier . '_' . $total_weight . '_' . $id_zone; if (!isset(self::$price_by_weight[$cache_key])) { $sql = 'SELECT d.`price` FROM `' . _DB_PREFIX_ . 'delivery` d LEFT JOIN `' . _DB_PREFIX_ . 'range_weight` w ON (d.`id_range_weight` = w.`id_range_weight`) WHERE d.`id_zone` = ' . (int) $id_zone . ' AND ' . (float) $total_weight . ' >= w.`delimiter1` AND ' . (float) $total_weight . ' < w.`delimiter2` AND d.`id_carrier` = ' . $id_carrier . ' ' . Carrier::sqlDeliveryRangeShop('range_weight') . ' ORDER BY w.`delimiter1` ASC'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); if (!isset($result['price'])) { self::$price_by_weight[$cache_key] = $this->getMaxDeliveryPriceByWeight($id_zone); } else { self::$price_by_weight[$cache_key] = $result['price']; } } $price_by_weight = Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]); if (is_numeric($price_by_weight)) { self::$price_by_weight[$cache_key] = $price_by_weight; } return self::$price_by_weight[$cache_key]; } /** * Check if the carrier is available for a given weight and zone * * @param int $id_carrier Carrier ID * @param float $total_weight Total weight * @param int $id_zone Zone ID * * @return bool true if carrier is available */ public static function checkDeliveryPriceByWeight($id_carrier, $total_weight, $id_zone) { $id_carrier = (int) $id_carrier; $cache_key = $id_carrier . '_' . $total_weight . '_' . $id_zone; if (!isset(self::$price_by_weight2[$cache_key])) { $sql = 'SELECT d.`price` FROM `' . _DB_PREFIX_ . 'delivery` d LEFT JOIN `' . _DB_PREFIX_ . 'range_weight` w ON d.`id_range_weight` = w.`id_range_weight` WHERE d.`id_zone` = ' . (int) $id_zone . ' AND ' . (float) $total_weight . ' >= w.`delimiter1` AND ' . (float) $total_weight . ' < w.`delimiter2` AND d.`id_carrier` = ' . $id_carrier . ' ' . Carrier::sqlDeliveryRangeShop('range_weight') . ' ORDER BY w.`delimiter1` ASC'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); self::$price_by_weight2[$cache_key] = (isset($result['price'])); } $price_by_weight = Hook::exec('actionDeliveryPriceByWeight', ['id_carrier' => $id_carrier, 'total_weight' => $total_weight, 'id_zone' => $id_zone]); if (is_numeric($price_by_weight)) { self::$price_by_weight2[$cache_key] = true; } return self::$price_by_weight2[$cache_key]; } /** * Get maximum delivery price when range weight is used. * * @param int $id_zone Zone ID * * @return false|string|null Maximum delivery price */ public function getMaxDeliveryPriceByWeight($id_zone) { $cache_id = 'Carrier::getMaxDeliveryPriceByWeight_' . (int) $this->id . '-' . (int) $id_zone; if (!Cache::isStored($cache_id)) { $sql = 'SELECT d.`price` FROM `' . _DB_PREFIX_ . 'delivery` d INNER JOIN `' . _DB_PREFIX_ . 'range_weight` w ON d.`id_range_weight` = w.`id_range_weight` WHERE d.`id_zone` = ' . (int) $id_zone . ' AND d.`id_carrier` = ' . (int) $this->id . ' ' . Carrier::sqlDeliveryRangeShop('range_weight') . ' ORDER BY w.`delimiter2` DESC'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); Cache::store($cache_id, $result); return $result; } return Cache::retrieve($cache_id); } /** * Get delivery price for a given order by total order price MINUS shipping costs. * * @param float $order_total Order total to pay * @param int $id_zone Zone id (for customer delivery address) * @param int|null $id_currency Currency ID * * @return float Maximum delivery price */ public function getDeliveryPriceByPrice($order_total, $id_zone, $id_currency = null) { $id_carrier = (int) $this->id; $cache_key = $this->id . '_' . $order_total . '_' . $id_zone . '_' . $id_currency; if (!isset(self::$price_by_price[$cache_key])) { if (!empty($id_currency)) { $order_total = Tools::convertPrice($order_total, $id_currency, false); } $sql = 'SELECT d.`price` FROM `' . _DB_PREFIX_ . 'delivery` d LEFT JOIN `' . _DB_PREFIX_ . 'range_price` r ON d.`id_range_price` = r.`id_range_price` WHERE d.`id_zone` = ' . (int) $id_zone . ' AND ' . (float) $order_total . ' >= r.`delimiter1` AND ' . (float) $order_total . ' < r.`delimiter2` AND d.`id_carrier` = ' . $id_carrier . ' ' . Carrier::sqlDeliveryRangeShop('range_price') . ' ORDER BY r.`delimiter1` ASC'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); if (!isset($result['price'])) { self::$price_by_price[$cache_key] = $this->getMaxDeliveryPriceByPrice($id_zone); } else { self::$price_by_price[$cache_key] = $result['price']; } } $price_by_price = Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]); if (is_numeric($price_by_price)) { self::$price_by_price[$cache_key] = $price_by_price; } return self::$price_by_price[$cache_key]; } /** * Check if the carrier is available for a given order total, currency and zone * * @param int $id_carrier Carrier ID * @param float $order_total Order total to pay * @param int $id_zone Zone id (for customer delivery address) * @param int|null $id_currency Currency ID * * @return bool true if carrier is available */ public static function checkDeliveryPriceByPrice($id_carrier, $order_total, $id_zone, $id_currency = null) { $id_carrier = (int) $id_carrier; $cache_key = $id_carrier . '_' . $order_total . '_' . $id_zone . '_' . $id_currency; if (!isset(self::$price_by_price2[$cache_key])) { if (!empty($id_currency)) { $order_total = Tools::convertPrice($order_total, $id_currency, false); } $sql = 'SELECT d.`price` FROM `' . _DB_PREFIX_ . 'delivery` d LEFT JOIN `' . _DB_PREFIX_ . 'range_price` r ON d.`id_range_price` = r.`id_range_price` WHERE d.`id_zone` = ' . (int) $id_zone . ' AND ' . (float) $order_total . ' >= r.`delimiter1` AND ' . (float) $order_total . ' < r.`delimiter2` AND d.`id_carrier` = ' . $id_carrier . ' ' . Carrier::sqlDeliveryRangeShop('range_price') . ' ORDER BY r.`delimiter1` ASC'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); self::$price_by_price2[$cache_key] = (isset($result['price'])); } $price_by_price = Hook::exec('actionDeliveryPriceByPrice', ['id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone]); if (is_numeric($price_by_price)) { self::$price_by_price2[$cache_key] = true; } return self::$price_by_price2[$cache_key]; } /** * Get maximum delivery price by order total MINUS shipping costs. * * @param int $id_zone Zone ID * * @return false|string Maximum delivery price */ public function getMaxDeliveryPriceByPrice($id_zone) { $cache_id = 'Carrier::getMaxDeliveryPriceByPrice_' . (int) $this->id . '-' . (int) $id_zone; if (!Cache::isStored($cache_id)) { $sql = 'SELECT d.`price` FROM `' . _DB_PREFIX_ . 'delivery` d INNER JOIN `' . _DB_PREFIX_ . 'range_price` r ON d.`id_range_price` = r.`id_range_price` WHERE d.`id_zone` = ' . (int) $id_zone . ' AND d.`id_carrier` = ' . (int) $this->id . ' ' . Carrier::sqlDeliveryRangeShop('range_price') . ' ORDER BY r.`delimiter2` DESC'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); Cache::store($cache_id, $result); } return Cache::retrieve($cache_id); } /** * Get delivery prices for a given shipping method (price/weight). * * @param string $range_table Table name (price or weight) * @param int $id_carrier Carrier ID * * @return array Delivery prices */ public static function getDeliveryPriceByRanges($range_table, $id_carrier) { $sql = 'SELECT d.`id_' . bqSQL($range_table) . '`, d.id_carrier, d.id_zone, d.price FROM ' . _DB_PREFIX_ . 'delivery d LEFT JOIN `' . _DB_PREFIX_ . bqSQL($range_table) . '` r ON r.`id_' . bqSQL($range_table) . '` = d.`id_' . bqSQL($range_table) . '` WHERE d.id_carrier = ' . (int) $id_carrier . ' AND d.`id_' . bqSQL($range_table) . '` IS NOT NULL AND d.`id_' . bqSQL($range_table) . '` != 0 ' . Carrier::sqlDeliveryRangeShop($range_table) . ' ORDER BY r.delimiter1'; return Db::getInstance()->executeS($sql); } /** * Get all carriers in a given language. * * @param int $id_lang Language id * @param int $modules_filters Possible values: * - PS_CARRIERS_ONLY * - CARRIERS_MODULE * - CARRIERS_MODULE_NEED_RANGE * - PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE * - ALL_CARRIERS * @param bool $active Returns only active carriers when true * @param array|string|null $ids_group * * @return array Carriers */ public static function getCarriers($id_lang, $active = false, $delete = false, $id_zone = false, $ids_group = null, $modules_filters = self::PS_CARRIERS_ONLY) { // Filter by groups and no groups => return empty array if ($ids_group && !is_array($ids_group)) { return []; } $sql = 'SELECT c.*, cl.delay FROM `' . _DB_PREFIX_ . 'carrier` c LEFT JOIN `' . _DB_PREFIX_ . 'carrier_lang` cl ON (c.`id_carrier` = cl.`id_carrier` AND cl.`id_lang` = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('cl') . ') LEFT JOIN `' . _DB_PREFIX_ . 'carrier_zone` cz ON (cz.`id_carrier` = c.`id_carrier`)' . ($id_zone ? 'LEFT JOIN `' . _DB_PREFIX_ . 'zone` z ON (z.`id_zone` = ' . (int) $id_zone . ')' : '') . ' ' . Shop::addSqlAssociation('carrier', 'c') . ' WHERE c.`deleted` = ' . ($delete ? '1' : '0'); if ($active) { $sql .= ' AND c.`active` = 1 '; } if ($id_zone) { $sql .= ' AND cz.`id_zone` = ' . (int) $id_zone . ' AND z.`active` = 1 '; } if ($ids_group) { $sql .= ' AND EXISTS (' . 'SELECT 1 FROM ' . _DB_PREFIX_ . 'carrier_group ' . 'WHERE ' . _DB_PREFIX_ . 'carrier_group.id_carrier = c.id_carrier ' . 'AND id_group IN (' . implode(',', array_map('intval', $ids_group)) . ')' . ') '; } switch ($modules_filters) { case 1: $sql .= ' AND c.is_module = 0 '; break; case 2: $sql .= ' AND c.is_module = 1 '; break; case 3: $sql .= ' AND c.is_module = 1 AND c.need_range = 1 '; break; case 4: $sql .= ' AND (c.is_module = 0 OR c.need_range = 1) '; break; } $sql .= ' GROUP BY c.`id_carrier` ORDER BY c.`position` ASC'; $cache_id = 'Carrier::getCarriers_' . md5($sql); if (!Cache::isStored($cache_id)) { $carriers = Db::getInstance()->executeS($sql); Cache::store($cache_id, $carriers); } else { $carriers = Cache::retrieve($cache_id); } return $carriers; } /** * Get most used Tax rules group. * * @return false|string|null Most used Tax rules group ID */ public static function getIdTaxRulesGroupMostUsed() { return Db::getInstance()->getValue( 'SELECT id_tax_rules_group FROM ( SELECT COUNT(*) n, c.id_tax_rules_group FROM ' . _DB_PREFIX_ . 'carrier_tax_rules_group_shop c JOIN ' . _DB_PREFIX_ . 'tax_rules_group trg ON (c.id_tax_rules_group = trg.id_tax_rules_group) WHERE trg.active = 1 AND trg.deleted = 0 GROUP BY c.id_tax_rules_group ORDER BY n DESC LIMIT 1 ) most_used' ); } /** * Get the countries to which can be delivered. * * @param int $id_lang Language ID * @param bool $active_countries Only return active countries when true * @param bool $active_carriers Only return active carriers when true * @param int|null $contain_states Only return countries with states * * @return array Countries to which can be delivered */ public static function getDeliveredCountries($id_lang, $active_countries = false, $active_carriers = false, $contain_states = null) { if (!Validate::isBool($active_countries)) { die(Tools::displayError('Parameter "active_countries" is invalid.')); } if (!Validate::isBool($active_carriers)) { die(Tools::displayError('Parameter "active_carriers" is invalid.')); } $states = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT s.* FROM `' . _DB_PREFIX_ . 'state` s ORDER BY s.`name` ASC'); $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT cl.*,c.*, cl.`name` AS country, zz.`name` AS zone FROM `' . _DB_PREFIX_ . 'country` c' . Shop::addSqlAssociation('country', 'c') . ' LEFT JOIN `' . _DB_PREFIX_ . 'country_lang` cl ON (c.`id_country` = cl.`id_country` AND cl.`id_lang` = ' . (int) $id_lang . ') INNER JOIN (`' . _DB_PREFIX_ . 'carrier_zone` cz INNER JOIN `' . _DB_PREFIX_ . 'carrier` cr ON ( cr.id_carrier = cz.id_carrier AND cr.deleted = 0 ' . ($active_carriers ? 'AND cr.active = 1) ' : ') ') . ' LEFT JOIN `' . _DB_PREFIX_ . 'zone` zz ON cz.id_zone = zz.id_zone) ON zz.`id_zone` = c.`id_zone` WHERE 1 ' . ($active_countries ? 'AND c.active = 1' : '') . ' ' . (null !== $contain_states ? 'AND c.`contains_states` = ' . (int) $contain_states : '') . ' ORDER BY cl.name ASC'); $countries = []; foreach ($result as $country) { $countries[$country['id_country']] = $country; } foreach ($states as $state) { if (isset($countries[$state['id_country']])) { /* Does not keep the state if its country has been disabled and not selected */ if ($state['active'] == 1) { $countries[$state['id_country']]['states'][] = $state; } } } return $countries; } /** * Return the default carrier to use. * * @param array $carriers Carriers * @param int $default_carrier The last selected Carrier ID * * @return number the id of the default carrier */ public static function getDefaultCarrierSelection($carriers, $default_carrier = 0) { if (empty($carriers)) { return 0; } if ((int) $default_carrier != 0) { foreach ($carriers as $carrier) { if ($carrier['id_carrier'] == (int) $default_carrier) { return (int) $carrier['id_carrier']; } } } foreach ($carriers as $carrier) { if ($carrier['id_carrier'] == (int) Configuration::get('PS_CARRIER_DEFAULT')) { return (int) $carrier['id_carrier']; } } return (int) $carriers[0]['id_carrier']; } /** * Get available Carriers for Order. * * @param int $id_zone Zone ID * @param array|null $groups Group of the Customer * @param CartCore|null $cart Optional Cart object * @param array $error Contains an error message if an error occurs * * @return array Carriers for the order */ public static function getCarriersForOrder($id_zone, $groups = null, $cart = null, &$error = []) { $context = Context::getContext(); $id_lang = $context->language->id; if (null === $cart) { $cart = $context->cart; } if (isset($context->currency)) { $id_currency = $context->currency->id; } if (is_array($groups) && !empty($groups)) { $result = Carrier::getCarriers($id_lang, true, false, (int) $id_zone, $groups, self::PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE); } else { $result = Carrier::getCarriers($id_lang, true, false, (int) $id_zone, [Configuration::get('PS_UNIDENTIFIED_GROUP')], self::PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE); } $results_array = []; foreach ($result as $k => $row) { $carrier = new Carrier((int) $row['id_carrier']); $shipping_method = $carrier->getShippingMethod(); if ($shipping_method != Carrier::SHIPPING_METHOD_FREE) { // Get only carriers that are compliant with shipping method if (($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT && $carrier->getMaxDeliveryPriceByWeight($id_zone) === false)) { $error[$carrier->id] = Carrier::SHIPPING_WEIGHT_EXCEPTION; unset($result[$k]); continue; } if (($shipping_method == Carrier::SHIPPING_METHOD_PRICE && $carrier->getMaxDeliveryPriceByPrice($id_zone) === false)) { $error[$carrier->id] = Carrier::SHIPPING_PRICE_EXCEPTION; unset($result[$k]); continue; } // If out-of-range behavior carrier is set to "Deactivate carrier" if ($row['range_behavior']) { // Get id zone if (!$id_zone) { $id_zone = (int) Country::getIdZone((int) Configuration::get('PS_COUNTRY_DEFAULT')); } // Get only carriers that have a range compatible with cart if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT && (Carrier::checkDeliveryPriceByWeight($row['id_carrier'], $cart->getTotalWeight(), $id_zone) === false)) { $error[$carrier->id] = Carrier::SHIPPING_WEIGHT_EXCEPTION; unset($result[$k]); continue; } if ($shipping_method == Carrier::SHIPPING_METHOD_PRICE && (Carrier::checkDeliveryPriceByPrice($row['id_carrier'], $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING), $id_zone, $id_currency ?? null) === false)) { $error[$carrier->id] = Carrier::SHIPPING_PRICE_EXCEPTION; unset($result[$k]); continue; } } } $row['price'] = (($shipping_method == Carrier::SHIPPING_METHOD_FREE) ? 0 : $cart->getPackageShippingCost((int) $row['id_carrier'], true, null, null, $id_zone)); $row['price_tax_exc'] = (($shipping_method == Carrier::SHIPPING_METHOD_FREE) ? 0 : $cart->getPackageShippingCost((int) $row['id_carrier'], false, null, null, $id_zone)); $row['img'] = file_exists(_PS_SHIP_IMG_DIR_ . (int) $row['id_carrier'] . '.jpg') ? _THEME_SHIP_DIR_ . (int) $row['id_carrier'] . '.jpg' : ''; // If price is false, then the carrier is unavailable (carrier module) if ($row['price'] === false) { unset($result[$k]); continue; } $results_array[] = $row; } // if we have to sort carriers by price $prices = []; if (Configuration::get('PS_CARRIER_DEFAULT_SORT') == Carrier::SORT_BY_PRICE) { foreach ($results_array as $r) { $prices[] = $r['price']; } if (Configuration::get('PS_CARRIER_DEFAULT_ORDER') == Carrier::SORT_BY_ASC) { array_multisort($prices, SORT_ASC, SORT_NUMERIC, $results_array); } else { array_multisort($prices, SORT_DESC, SORT_NUMERIC, $results_array); } } return $results_array; } public static function checkCarrierZone($id_carrier, $id_zone) { $cache_id = 'Carrier::checkCarrierZone_' . (int) $id_carrier . '-' . (int) $id_zone; if (!Cache::isStored($cache_id)) { $sql = 'SELECT c.`id_carrier` FROM `' . _DB_PREFIX_ . 'carrier` c LEFT JOIN `' . _DB_PREFIX_ . 'carrier_zone` cz ON (cz.`id_carrier` = c.`id_carrier`) LEFT JOIN `' . _DB_PREFIX_ . 'zone` z ON (z.`id_zone` = ' . (int) $id_zone . ') WHERE c.`id_carrier` = ' . (int) $id_carrier . ' AND c.`deleted` = 0 AND c.`active` = 1 AND cz.`id_zone` = ' . (int) $id_zone . ' AND z.`active` = 1'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); Cache::store($cache_id, $result); } return Cache::retrieve($cache_id); } /** * Get all zones. * * @return array Zones */ public function getZones() { return Db::getInstance()->executeS(' SELECT * FROM `' . _DB_PREFIX_ . 'carrier_zone` cz LEFT JOIN `' . _DB_PREFIX_ . 'zone` z ON cz.`id_zone` = z.`id_zone` WHERE cz.`id_carrier` = ' . (int) $this->id); } /** * Get a specific zones. * * @return array Zone */ public function getZone($id_zone) { return Db::getInstance()->executeS(' SELECT * FROM `' . _DB_PREFIX_ . 'carrier_zone` WHERE `id_carrier` = ' . (int) $this->id . ' AND `id_zone` = ' . (int) $id_zone); } /** * Add zone. */ public function addZone($id_zone) { if (Db::getInstance()->execute(' INSERT INTO `' . _DB_PREFIX_ . 'carrier_zone` (`id_carrier` , `id_zone`) VALUES (' . (int) $this->id . ', ' . (int) $id_zone . ') ')) { // Get all ranges for this carrier $ranges_price = RangePrice::getRanges($this->id); $ranges_weight = RangeWeight::getRanges($this->id); // Create row in ps_delivery table if (count($ranges_price) || count($ranges_weight)) { $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'delivery` (`id_carrier`, `id_range_price`, `id_range_weight`, `id_zone`, `price`) VALUES '; if (count($ranges_price)) { foreach ($ranges_price as $range) { $sql .= '(' . (int) $this->id . ', ' . (int) $range['id_range_price'] . ', 0, ' . (int) $id_zone . ', 0),'; } } if (count($ranges_weight)) { foreach ($ranges_weight as $range) { $sql .= '(' . (int) $this->id . ', 0, ' . (int) $range['id_range_weight'] . ', ' . (int) $id_zone . ', 0),'; } } $sql = rtrim($sql, ','); return Db::getInstance()->execute($sql); } return true; } return false; } /** * Delete zone. */ public function deleteZone($id_zone) { if (Db::getInstance()->execute(' DELETE FROM `' . _DB_PREFIX_ . 'carrier_zone` WHERE `id_carrier` = ' . (int) $this->id . ' AND `id_zone` = ' . (int) $id_zone . ' LIMIT 1 ')) { return Db::getInstance()->execute(' DELETE FROM `' . _DB_PREFIX_ . 'delivery` WHERE `id_carrier` = ' . (int) $this->id . ' AND `id_zone` = ' . (int) $id_zone); } return false; } /** * Gets a specific group. * * @since 1.5.0 * * @return array Group */ public function getGroups() { return Db::getInstance()->executeS(' SELECT id_group FROM ' . _DB_PREFIX_ . 'carrier_group WHERE id_carrier=' . (int) $this->id); } /** * Clean delivery prices (weight/price). * * @param string $range_table Table name to clean (weight or price according to shipping method) * * @return bool Deletion result */ public function deleteDeliveryPrice($range_table) { $where = '`id_carrier` = ' . (int) $this->id . ' AND (`id_' . bqSQL($range_table) . '` IS NOT NULL OR `id_' . bqSQL($range_table) . '` = 0) '; if (Shop::getContext() == Shop::CONTEXT_ALL) { $where .= 'AND id_shop IS NULL AND id_shop_group IS NULL'; } elseif (Shop::getContext() == Shop::CONTEXT_GROUP) { $where .= 'AND id_shop IS NULL AND id_shop_group = ' . (int) Shop::getContextShopGroupID(); } else { $where .= 'AND id_shop = ' . (int) Shop::getContextShopID(); } return Db::getInstance()->delete('delivery', $where); } /** * Add new delivery prices. * * @param array $price_list Prices list in multiple arrays (changed to array since 1.5.0) * @param bool $delete * * @return bool Insertion result */ public function addDeliveryPrice($price_list, $delete = false) { if (!$price_list) { return false; } $keys = array_keys($price_list[0]); if (!in_array('id_shop', $keys)) { $keys[] = 'id_shop'; } if (!in_array('id_shop_group', $keys)) { $keys[] = 'id_shop_group'; } $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'delivery` (' . implode(', ', $keys) . ') VALUES '; foreach ($price_list as $values) { if (!isset($values['id_shop'])) { $values['id_shop'] = (Shop::getContext() == Shop::CONTEXT_SHOP) ? Shop::getContextShopID() : null; } if (!isset($values['id_shop_group'])) { $values['id_shop_group'] = (Shop::getContext() != Shop::CONTEXT_ALL) ? Shop::getContextShopGroupID() : null; } if ($delete) { Db::getInstance()->execute( 'DELETE FROM `' . _DB_PREFIX_ . 'delivery` WHERE ' . (null === $values['id_shop'] ? 'ISNULL(`id_shop`) ' : 'id_shop = ' . (int) $values['id_shop']) . ' AND ' . (null === $values['id_shop_group'] ? 'ISNULL(`id_shop`) ' : 'id_shop_group=' . (int) $values['id_shop_group']) . ' AND id_carrier=' . (int) $values['id_carrier'] . ($values['id_range_price'] !== null ? ' AND id_range_price=' . (int) $values['id_range_price'] : ' AND (ISNULL(`id_range_price`) OR `id_range_price` = 0)') . ($values['id_range_weight'] !== null ? ' AND id_range_weight=' . (int) $values['id_range_weight'] : ' AND (ISNULL(`id_range_weight`) OR `id_range_weight` = 0)') . ' AND id_zone=' . (int) $values['id_zone'] ); } $sql .= '('; foreach ($values as $v) { if (null === $v) { $sql .= 'NULL'; } elseif (is_int($v) || is_float($v)) { $sql .= $v; } else { $sql .= '\'' . Db::getInstance()->escape($v, false, true) . '\''; } $sql .= ', '; } $sql = rtrim($sql, ', ') . '), '; } $sql = rtrim($sql, ', '); return Db::getInstance()->execute($sql); } /** * Copy old carrier informations when update carrier. * * @param int $old_id Old id carrier (copy from that id) */ public function copyCarrierData($old_id) { if (!Validate::isUnsignedId($old_id)) { throw new PrestaShopException('Incorrect identifier for carrier'); } if (!$this->id) { return false; } $old_logo = _PS_SHIP_IMG_DIR_ . '/' . (int) $old_id . '.jpg'; if (file_exists($old_logo)) { copy($old_logo, _PS_SHIP_IMG_DIR_ . '/' . (int) $this->id . '.jpg'); } $old_tmp_logo = _PS_TMP_IMG_DIR_ . '/carrier_mini_' . (int) $old_id . '.jpg'; if (file_exists($old_tmp_logo)) { if (!isset($_FILES['logo'])) { copy($old_tmp_logo, _PS_TMP_IMG_DIR_ . '/carrier_mini_' . $this->id . '.jpg'); } unlink($old_tmp_logo); } // Copy existing ranges price foreach (['range_price', 'range_weight'] as $range) { $res = Db::getInstance()->executeS(' SELECT `id_' . $range . '` as id_range, `delimiter1`, `delimiter2` FROM `' . _DB_PREFIX_ . $range . '` WHERE `id_carrier` = ' . (int) $old_id); if (count($res)) { foreach ($res as $val) { Db::getInstance()->execute(' INSERT INTO `' . _DB_PREFIX_ . $range . '` (`id_carrier`, `delimiter1`, `delimiter2`) VALUES (' . (int) $this->id . ',' . (float) $val['delimiter1'] . ',' . (float) $val['delimiter2'] . ')'); $range_id = (int) Db::getInstance()->Insert_ID(); $range_price_id = ($range == 'range_price') ? $range_id : 'NULL'; $range_weight_id = ($range == 'range_weight') ? $range_id : 'NULL'; Db::getInstance()->execute(' INSERT INTO `' . _DB_PREFIX_ . 'delivery` (`id_carrier`, `id_shop`, `id_shop_group`, `id_range_price`, `id_range_weight`, `id_zone`, `price`) ( SELECT ' . (int) $this->id . ', `id_shop`, `id_shop_group`, ' . (int) $range_price_id . ', ' . (int) $range_weight_id . ', `id_zone`, `price` FROM `' . _DB_PREFIX_ . 'delivery` WHERE `id_carrier` = ' . (int) $old_id . ' AND `id_' . $range . '` = ' . (int) $val['id_range'] . ' ) '); } } } // Copy existing zones $res = Db::getInstance()->executeS(' SELECT * FROM `' . _DB_PREFIX_ . 'carrier_zone` WHERE id_carrier = ' . (int) $old_id); foreach ($res as $val) { Db::getInstance()->execute(' INSERT INTO `' . _DB_PREFIX_ . 'carrier_zone` (`id_carrier`, `id_zone`) VALUES (' . (int) $this->id . ',' . (int) $val['id_zone'] . ') '); } //Copy default carrier if (Configuration::get('PS_CARRIER_DEFAULT') == $old_id) { Configuration::updateValue('PS_CARRIER_DEFAULT', (int) $this->id); } // Copy reference $id_reference = Db::getInstance()->getValue(' SELECT `id_reference` FROM `' . _DB_PREFIX_ . $this->def['table'] . '` WHERE id_carrier = ' . (int) $old_id); Db::getInstance()->execute(' UPDATE `' . _DB_PREFIX_ . $this->def['table'] . '` SET `id_reference` = ' . (int) $id_reference . ' WHERE `id_carrier` = ' . (int) $this->id); $this->id_reference = (int) $id_reference; // Copy tax rules group Db::getInstance()->execute(' INSERT INTO `' . _DB_PREFIX_ . 'carrier_tax_rules_group_shop` (`id_carrier`, `id_tax_rules_group`, `id_shop`) (SELECT ' . (int) $this->id . ', `id_tax_rules_group`, `id_shop` FROM `' . _DB_PREFIX_ . 'carrier_tax_rules_group_shop` WHERE `id_carrier`=' . (int) $old_id . ')'); } /** * Get carrier using the reference id. */ public static function getCarrierByReference($id_reference, $id_lang = null) { /** @todo class var $table must became static. here I have to use 'carrier' because this method is static */ $id_carrier = Db::getInstance()->getValue('SELECT `id_carrier` FROM `' . _DB_PREFIX_ . 'carrier` WHERE id_reference = ' . (int) $id_reference . ' AND deleted = 0 ORDER BY id_carrier DESC'); if (!$id_carrier) { return false; } return new Carrier((int) $id_carrier, $id_lang); } /** * Check if Carrier is used (at least one order placed). * * @return int Order count for this carrier */ public function isUsed() { $row = Db::getInstance()->getRow(' SELECT COUNT(`id_carrier`) AS total FROM `' . _DB_PREFIX_ . 'orders` WHERE `id_carrier` = ' . (int) $this->id); return (int) $row['total']; } /** * Get shipping method of the carrier (free, weight or price). * * @return int Shipping method enumerator */ public function getShippingMethod() { if ($this->is_free) { return Carrier::SHIPPING_METHOD_FREE; } $method = (int) $this->shipping_method; if ($this->shipping_method == Carrier::SHIPPING_METHOD_DEFAULT) { // backward compatibility if ((int) Configuration::get('PS_SHIPPING_METHOD')) { $method = Carrier::SHIPPING_METHOD_WEIGHT; } else { $method = Carrier::SHIPPING_METHOD_PRICE; } } return $method; } /** * Get range table of carrier. * * @return bool|string Range table, false if not found */ public function getRangeTable() { $shipping_method = $this->getShippingMethod(); if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT) { return 'range_weight'; } elseif ($shipping_method == Carrier::SHIPPING_METHOD_PRICE) { return 'range_price'; } return false; } /** * Get Range object, price or weight, depending on the shipping method given. * * @param int|bool $shipping_method Shipping method enumerator * Use false in order to let this method find the correct one * * @return bool|RangePrice|RangeWeight */ public function getRangeObject($shipping_method = false) { if (!$shipping_method) { $shipping_method = $this->getShippingMethod(); } if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT) { return new RangeWeight(); } elseif ($shipping_method == Carrier::SHIPPING_METHOD_PRICE) { return new RangePrice(); } return false; } /** * Get range suffix. * * @param Currency|null $currency Currency * * @return string Currency sign in suffix to use for the range */ public function getRangeSuffix($currency = null) { if (!$currency) { $currency = Context::getContext()->currency; } $suffix = Configuration::get('PS_WEIGHT_UNIT'); if ($this->getShippingMethod() == Carrier::SHIPPING_METHOD_PRICE) { $suffix = $currency->sign; } return $suffix; } /** * Get TaxRulesGroup ID for this Carrier. * * @param Context|null $context Context * * @return int TaxrulesGroup ID */ public function getIdTaxRulesGroup(Context $context = null) { return Carrier::getIdTaxRulesGroupByIdCarrier((int) $this->id, $context); } /** * Get TaxRulesGroup ID for a given Carrier. * * @param int $id_carrier Carrier ID * @param Context|null $context Context * * @return int TaxRulesGroup ID * false if not found */ public static function getIdTaxRulesGroupByIdCarrier($id_carrier, Context $context = null) { if (!$context) { $context = Context::getContext(); } $key = 'carrier_id_tax_rules_group_' . (int) $id_carrier . '_' . (int) $context->shop->id; if (!Cache::isStored($key)) { $result = Db::getInstance(_PS_USE_SQL_SLAVE_) ->getValue(' SELECT `id_tax_rules_group` FROM `' . _DB_PREFIX_ . 'carrier_tax_rules_group_shop` WHERE `id_carrier` = ' . (int) $id_carrier . ' AND id_shop=' . (int) Context::getContext()->shop->id); Cache::store($key, $result); return (int) $result; } return (int) Cache::retrieve($key); } /** * Set TaxRulesGroup. * * @param int $id_tax_rules_group Set the TaxRulesGroup with the given ID * as this Carrier's TaxRulesGroup * @param bool $all_shops True if this should be done for all shops * * @return bool Whether the TaxRulesGroup has been succesfully set * for this Carrier in this Shop or all given Shops */ public function setTaxRulesGroup($id_tax_rules_group, $all_shops = false) { if (!Validate::isUnsignedId($id_tax_rules_group)) { die(Tools::displayError('Parameter "id_tax_rules_group" is invalid.')); } if (!$all_shops) { $shops = Shop::getContextListShopID(); } else { $shops = Shop::getShops(true, null, true); } $this->deleteTaxRulesGroup($shops); $values = []; foreach ($shops as $id_shop) { $values[] = [ 'id_carrier' => (int) $this->id, 'id_tax_rules_group' => (int) $id_tax_rules_group, 'id_shop' => (int) $id_shop, ]; } Cache::clean('carrier_id_tax_rules_group_' . (int) $this->id . '_' . (int) Context::getContext()->shop->id); return Db::getInstance()->insert('carrier_tax_rules_group_shop', $values); } /** * Delete TaxRulesGroup from this Carrier. * * @param array|null $shops Shops * * @return bool Whether the TaxRulesGroup has been successfully removed from this Carrier */ public function deleteTaxRulesGroup(array $shops = null) { if (!$shops) { $shops = Shop::getContextListShopID(); } $where = 'id_carrier = ' . (int) $this->id; if ($shops) { $where .= ' AND id_shop IN(' . implode(', ', array_map('intval', $shops)) . ')'; } return Db::getInstance()->delete('carrier_tax_rules_group_shop', $where); } /** * Returns the Tax rates associated to the Carrier. * * @since 1.5 * * @param Address $address Address optional * * @return float Total Tax rate for this Carrier */ public function getTaxesRate(Address $address = null) { if (!$address || !$address->id_country) { $address = Address::initialize(); } $tax_calculator = $this->getTaxCalculator($address); return $tax_calculator->getTotalRate(); } /** * Returns the taxes calculator associated to the carrier. * * @since 1.5 * * @param Address $address Address * * @return TaxCalculator|AverageTaxOfProductsTaxCalculator Tax calculator object */ public function getTaxCalculator(Address $address, $id_order = null, $use_average_tax_of_products = false) { if ($use_average_tax_of_products) { return ServiceLocator::get('AverageTaxOfProductsTaxCalculator')->setIdOrder($id_order); } else { $tax_manager = TaxManagerFactory::getManager($address, $this->getIdTaxRulesGroup()); return $tax_manager->getTaxCalculator(); } } /** * This tricky method generates a SQL clause to check if ranged data are overloaded by multishop. * * @since 1.5.0 * * @param string $range_table Range table * * @return string SQL quoer to get the delivery range table in this Shop(Group) */ public static function sqlDeliveryRangeShop($range_table, $alias = 'd') { if (Shop::getContext() == Shop::CONTEXT_ALL) { $where = 'AND d2.id_shop IS NULL AND d2.id_shop_group IS NULL'; } elseif (Shop::getContext() == Shop::CONTEXT_GROUP) { $where = 'AND ((d2.id_shop_group IS NULL OR d2.id_shop_group = ' . (int) Shop::getContextShopGroupID() . ') AND d2.id_shop IS NULL)'; } else { $where = 'AND (d2.id_shop = ' . (int) Shop::getContextShopID() . ' OR (d2.id_shop_group = ' . (int) Shop::getContextShopGroupID() . ' AND d2.id_shop IS NULL) OR (d2.id_shop_group IS NULL AND d2.id_shop IS NULL))'; } $sql = 'AND ' . $alias . '.id_delivery = ( SELECT d2.id_delivery FROM ' . _DB_PREFIX_ . 'delivery d2 WHERE d2.id_carrier = `' . bqSQL($alias) . '`.id_carrier AND d2.id_zone = `' . bqSQL($alias) . '`.id_zone AND d2.`id_' . bqSQL($range_table) . '` = `' . bqSQL($alias) . '`.`id_' . bqSQL($range_table) . '` ' . $where . ' ORDER BY d2.id_shop DESC, d2.id_shop_group DESC LIMIT 1 )'; return $sql; } /** * Moves a carrier. * * @since 1.5.0 * * @param bool $way Up (1) or Down (0) * @param int|null $position Current position of the Carrier * * @return bool Whether the update was successful */ public function updatePosition($way, $position) { if (!$res = Db::getInstance()->executeS( 'SELECT `id_carrier`, `position` FROM `' . _DB_PREFIX_ . 'carrier` WHERE `deleted` = 0 ORDER BY `position` ASC' )) { return false; } foreach ($res as $carrier) { if ((int) $carrier['id_carrier'] == (int) $this->id) { $moved_carrier = $carrier; } } if (!isset($moved_carrier) || !isset($position)) { return false; } // < and > statements rather than BETWEEN operator // since BETWEEN is treated differently according to databases return Db::getInstance()->execute(' UPDATE `' . _DB_PREFIX_ . 'carrier` SET `position`= `position` ' . ($way ? '- 1' : '+ 1') . ' WHERE `position` ' . ($way ? '> ' . (int) $moved_carrier['position'] . ' AND `position` <= ' . (int) $position : '< ' . (int) $moved_carrier['position'] . ' AND `position` >= ' . (int) $position . ' AND `deleted` = 0')) && Db::getInstance()->execute(' UPDATE `' . _DB_PREFIX_ . 'carrier` SET `position` = ' . (int) $position . ' WHERE `id_carrier` = ' . (int) $moved_carrier['id_carrier']); } /** * Reorder Carrier positions * Called after deleting a Carrier. * * @since 1.5.0 * * @return bool $return */ public static function cleanPositions() { $return = true; $sql = 'SELECT `id_carrier` FROM `' . _DB_PREFIX_ . 'carrier` WHERE `deleted` = 0 ORDER BY `position` ASC'; $result = Db::getInstance()->executeS($sql); $i = 0; foreach ($result as $value) { $return = Db::getInstance()->execute(' UPDATE `' . _DB_PREFIX_ . 'carrier` SET `position` = ' . (int) $i++ . ' WHERE `id_carrier` = ' . (int) $value['id_carrier']); } return $return; } /** * Gets the highest carrier position. * * @since 1.5.0 * * @return int $position */ public static function getHigherPosition() { $sql = 'SELECT MAX(`position`) FROM `' . _DB_PREFIX_ . 'carrier` WHERE `deleted` = 0'; $position = Db::getInstance()->getValue($sql); return (is_numeric($position)) ? $position : -1; } /** * For a given {product, warehouse}, gets the carrier available. * * @since 1.5.0 * * @param Product $product The id of the product, or an array with at least the package size and weight * @param int|null $id_warehouse Warehouse ID * @param int|null $id_address_delivery Delivery Address ID * @param int|null$id_shop Shop ID * @param CartCore|null $cart Cart object * @param array|null $error contain an error message if an error occurs * * @return array Available Carriers * * @throws PrestaShopDatabaseException */ public static function getAvailableCarrierList(Product $product, $id_warehouse, $id_address_delivery = null, $id_shop = null, $cart = null, &$error = []) { static $ps_country_default = null; if ($ps_country_default === null) { $ps_country_default = Configuration::get('PS_COUNTRY_DEFAULT'); } if (null === $id_shop) { $id_shop = Context::getContext()->shop->id; } if (null === $cart) { $cart = Context::getContext()->cart; } if (null === $error || !is_array($error)) { $error = []; } $id_address = (int) ((null !== $id_address_delivery && $id_address_delivery != 0) ? $id_address_delivery : $cart->id_address_delivery); if ($id_address) { $id_zone = Address::getZoneById($id_address); // Check the country of the address is activated if (!Address::isCountryActiveById($id_address)) { return []; } } else { $country = new Country($ps_country_default); $id_zone = $country->id_zone; } // Does the product is linked with carriers? $cache_id = 'Carrier::getAvailableCarrierList_' . (int) $product->id . '-' . (int) $id_shop; if (!Cache::isStored($cache_id)) { $query = new DbQuery(); $query->select('id_carrier'); $query->from('product_carrier', 'pc'); $query->innerJoin( 'carrier', 'c', 'c.id_reference = pc.id_carrier_reference AND c.deleted = 0 AND c.active = 1' ); $query->where('pc.id_product = ' . (int) $product->id); $query->where('pc.id_shop = ' . (int) $id_shop); $carriers_for_product = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); Cache::store($cache_id, $carriers_for_product); } else { $carriers_for_product = Cache::retrieve($cache_id); } $carrier_list = []; if (!empty($carriers_for_product)) { //the product is linked with carriers foreach ($carriers_for_product as $carrier) { //check if the linked carriers are available in current zone if (Carrier::checkCarrierZone($carrier['id_carrier'], $id_zone)) { $carrier_list[$carrier['id_carrier']] = $carrier['id_carrier']; } } if (empty($carrier_list)) { return []; }//no linked carrier are available for this zone } // The product is not directly linked with a carrier // Get all the carriers linked to a warehouse if ($id_warehouse) { $warehouse = new Warehouse($id_warehouse); $warehouse_carrier_list = $warehouse->getCarriers(); } $available_carrier_list = []; $cache_id = 'Carrier::getAvailableCarrierList_getCarriersForOrder_' . (int) $id_zone . '-' . (int) $cart->id; if (!Cache::isStored($cache_id)) { $customer = new Customer($cart->id_customer); $carrier_error = []; $carriers = Carrier::getCarriersForOrder($id_zone, $customer->getGroups(), $cart, $carrier_error); Cache::store($cache_id, [$carriers, $carrier_error]); } else { list($carriers, $carrier_error) = Cache::retrieve($cache_id); } $error = array_merge($error, $carrier_error); foreach ($carriers as $carrier) { $available_carrier_list[$carrier['id_carrier']] = $carrier['id_carrier']; } if ($carrier_list) { $carrier_list = array_intersect($available_carrier_list, $carrier_list); } else { $carrier_list = $available_carrier_list; } if (isset($warehouse_carrier_list)) { $carrier_list = array_intersect($carrier_list, $warehouse_carrier_list); } $cart_quantity = 0; $cart_weight = 0; foreach ($cart->getProducts(false, false) as $cart_product) { if ($cart_product['id_product'] == $product->id) { $cart_quantity += $cart_product['cart_quantity']; } if (isset($cart_product['weight_attribute']) && $cart_product['weight_attribute'] > 0) { $cart_weight += ($cart_product['weight_attribute'] * $cart_product['cart_quantity']); } else { $cart_weight += ($cart_product['weight'] * $cart_product['cart_quantity']); } } if ($product->width > 0 || $product->height > 0 || $product->depth > 0 || $product->weight > 0 || $cart_weight > 0) { foreach ($carrier_list as $key => $id_carrier) { $carrier = new Carrier($id_carrier); // Get the sizes of the carrier and the product and sort them to check if the carrier can take the product. $carrier_sizes = [ 'width' => (int) $carrier->max_width, 'height' => (int) $carrier->max_height, 'depth' => (int) $carrier->max_depth, ]; $product_sizes = [ 'width' => (int) $product->width, 'height' => (int) $product->height, 'depth' => (int) $product->depth, ]; if (($carrier_sizes['width'] > 0 && $carrier_sizes['width'] < $product_sizes['width']) || ($carrier_sizes['height'] > 0 && $carrier_sizes['height'] < $product_sizes['height']) || ($carrier_sizes['depth'] > 0 && $carrier_sizes['depth'] < $product_sizes['depth']) ) { $error[$carrier->id] = Carrier::SHIPPING_SIZE_EXCEPTION; unset($carrier_list[$key]); } if ($carrier->max_weight > 0 && ($carrier->max_weight < $product->weight * $cart_quantity || $carrier->max_weight < $cart_weight)) { $error[$carrier->id] = Carrier::SHIPPING_WEIGHT_EXCEPTION; unset($carrier_list[$key]); } } } return $carrier_list; } /** * Assign one (ore more) group to all carriers. * * @since 1.5.0 * * @param int|array $id_group_list Group ID or array of Group IDs * @param array $exception List of Carrier IDs to ignore * * @return bool */ public static function assignGroupToAllCarriers($id_group_list, $exception = []) { if (!is_array($id_group_list)) { $id_group_list = [$id_group_list]; } $id_group_list = array_map('intval', $id_group_list); $exception = array_map('intval', $exception); Db::getInstance()->execute(' DELETE FROM `' . _DB_PREFIX_ . 'carrier_group` WHERE `id_group` IN (' . implode(',', $id_group_list) . ')'); $carrier_list = Db::getInstance()->executeS(' SELECT id_carrier FROM `' . _DB_PREFIX_ . 'carrier` WHERE deleted = 0 ' . (is_array($exception) && count($exception) > 0 ? 'AND id_carrier NOT IN (' . implode(',', $exception) . ')' : '')); if ($carrier_list) { $data = []; foreach ($carrier_list as $carrier) { foreach ($id_group_list as $id_group) { $data[] = [ 'id_carrier' => $carrier['id_carrier'], 'id_group' => $id_group, ]; } } return Db::getInstance()->insert('carrier_group', $data, false, false, Db::INSERT); } return true; } /** * Set Carrier Groups. * * @param array $groups Carrier Groups * @param bool $delete Delete all previously Carrier Groups which * were linked to this Carrier * * @return bool Whether the Carrier Groups have been successfully set */ public function setGroups($groups, $delete = true) { if ($delete) { Db::getInstance()->execute('DELETE FROM ' . _DB_PREFIX_ . 'carrier_group WHERE id_carrier = ' . (int) $this->id); } if (!is_array($groups) || !count($groups)) { return true; } $sql = 'INSERT INTO ' . _DB_PREFIX_ . 'carrier_group (id_carrier, id_group) VALUES '; foreach ($groups as $id_group) { $sql .= '(' . (int) $this->id . ', ' . (int) $id_group . '),'; } return Db::getInstance()->execute(rtrim($sql, ',')); } }
Save
cmd:
run