Index: branches/5.2.x/units/shipping_quote_engines/shipping_quote_collector.php =================================================================== --- branches/5.2.x/units/shipping_quote_engines/shipping_quote_collector.php (revision 16639) +++ branches/5.2.x/units/shipping_quote_engines/shipping_quote_collector.php (revision 16640) @@ -1,196 +1,207 @@ Application->recallObject('CountryStatesHelper'); $has_states = $cs_helper->CountryHasStates($params['dest_country']); if ( !$params['dest_city'] || !$params['dest_country'] || ($has_states && !$params['dest_state']) || !$params['dest_postal'] || !$params['packages'] ) { return Array (); } $cached_var_name = 'ShippingQuotes' . crc32(serialize($params)); $shipping_types = $this->Application->getDBCache($cached_var_name); if ($shipping_types) { return unserialize($shipping_types); } $quotes_valid = true; $shipping_types = Array(); $classes = $this->getEngineClasses(); foreach ($classes as $class) { /** @var ShippingQuoteEngine $object */ $object = $this->Application->recallObject($class); $new_shipping_types = $object->GetShippingQuotes($params); if (is_array($new_shipping_types)) { $shipping_types = array_merge($shipping_types, $new_shipping_types); } else { $quotes_valid = false; } } uasort($shipping_types, Array(&$this, 'price_sort')); // exclude not available shipping quotes by products $limit_types = unserialize($params['limit_types']); - if (is_array($limit_types) && !in_array('ANY', $limit_types)) { - if (count($limit_types) == 0) { - break; - } - - $available_types = Array (); - foreach ($shipping_types as $a_type) { - $include = false; // exclude by default - - foreach ($limit_types as $limit) { - $include = $include || preg_match("/^$limit/", $a_type['ShippingId']); - if ($include) { - break; - } - } - - if (!$include) { - continue; - } - - $available_types[ $a_type['ShippingId'] ] = $a_type; - } - - $shipping_types = $available_types; + if ( is_array($limit_types) && count($limit_types) && !in_array('ANY', $limit_types) ) { + $shipping_types = $this->applyLimitations($shipping_types, $limit_types); } // exclude Selected Products Only shipping types, not matching products $available_types = Array(); foreach ($shipping_types as $a_type) { if (getArrayValue($a_type, 'SelectedOnly')) { if (!is_array($limit_types) || !in_array($a_type['ShippingId'], $limit_types)) { continue; } } $available_types[ $a_type['ShippingId'] ] = $a_type; } $shipping_types = $available_types; if ($quotes_valid) { $this->Application->setDBCache($cached_var_name, serialize($shipping_types), 24 * 3600); } return $shipping_types; } + /** + * Applies limitations to shipping types + * + * @param array $shipping_types Shipping types. + * @param array $limit_types Limit types. + * + * @return array + */ + protected function applyLimitations(array $shipping_types, array $limit_types) + { + $available_types = array(); + + foreach ( $shipping_types as $a_type ) { + $include = false; // Exclude by default. + + foreach ( $limit_types as $limit ) { + $include = $include || preg_match('/^' . $limit . '/', $a_type['ShippingId']); + + if ( $include ) { + break; + } + } + + if ( !$include ) { + continue; + } + + $available_types[$a_type['ShippingId']] = $a_type; + } + + return $available_types; + } + function GetAvailableShippingTypes() { $shipping_types = Array (); $classes = $this->getEngineClasses(); foreach ($classes as $class) { /** @var ShippingQuoteEngine $object */ $object = $this->Application->recallObject($class); $new_shipping_types = $object->GetAvailableTypes(); $shipping_types = array_merge($shipping_types, $new_shipping_types); } uasort($shipping_types, Array(&$this, 'SortShippingTypes')); return $shipping_types; } /** * Returns all enabled shipping quote engine classes * * @return Array */ function getEngineClasses() { $sql = 'SELECT Classname FROM ' . $this->Application->getUnitOption('sqe', 'TableName') . ' WHERE Status = ' . STATUS_ACTIVE; $classes = $this->Conn->GetCol($sql); // always persists $classes[] = 'CustomShippingQuoteEngine'; return $classes; } /** * Returns shipping quote engine, that matches shipping type used in order * * @param Array $shipping_info * @param int $package_num * @return ShippingQuoteEngine */ function &GetClassByType($shipping_info, $package_num = 1) { if ( !$shipping_info || !array_key_exists($package_num, $shipping_info) ) { return false; } $classes = $this->getEngineClasses(); $shipping_id = $shipping_info[$package_num]['ShippingId']; foreach ($classes as $class) { /** @var ShippingQuoteEngine $object */ $object = $this->Application->recallObject($class); $shipping_types = $object->GetAvailableTypes(); foreach ($shipping_types as $index => $shipping_type) { if ( preg_match('/^' . preg_quote($shipping_type['_Id'], '/') . '/', $shipping_id) ) { return $class; } } } return false; } function SortShippingTypes($elem1, $elem2) { if ($elem1['_Name'] == $elem2['_Name']) { return 0; } return $elem1['_Name'] < $elem2['_Name'] ? -1 : 1; } function price_sort($elem1, $elem2) { if ($elem1['TotalCost'] == $elem2['TotalCost']) { return 0; } return $elem1['TotalCost'] < $elem2['TotalCost'] ? -1 : 1; } }