Index: units/products/products_tag_processor.php =================================================================== --- units/products/products_tag_processor.php (revision 13756) +++ units/products/products_tag_processor.php (working copy) @@ -653,10 +653,11 @@ } } - function ListShippingTypes($params) { $quote_engine_collector =& $this->Application->recallObject('ShippingQuoteCollector'); + /* @var $quote_engine_collector ShippingQuoteCollector */ + $types = $quote_engine_collector->GetAvailableShippingTypes(); $object =& $this->getObject($params); Index: units/shipping/shipping_tag_processor.php =================================================================== --- units/shipping/shipping_tag_processor.php (revision 13756) +++ units/shipping/shipping_tag_processor.php (working copy) @@ -271,6 +271,8 @@ function AvailableTypes($params) { $quote_engine_collector =& $this->Application->recallObject('ShippingQuoteCollector'); + /* @var $quote_engine_collector ShippingQuoteCollector */ + $types = $quote_engine_collector->GetAvailableShippingTypes(); $o; @@ -291,7 +293,6 @@ $selected_arr = explode(',', $selected); $all_groups = $this->Conn->Query('SELECT GroupId, Name FROM '.TABLE_PREFIX.'PortalGroup ORDER BY NAME', 'GroupId'); - $o = ''; foreach ($all_groups as $a_group) { Index: units/shipping_quote_engines/intershipper.php =================================================================== --- units/shipping_quote_engines/intershipper.php (revision 13756) +++ units/shipping_quote_engines/intershipper.php (working copy) @@ -372,7 +372,7 @@ { $a_type['_ClassName'] = get_class($this); $a_type['_Id'] = 'INTSH_'.$carrier.'_'.$class; - $a_type['_Name'] = '(Intershipper)'.$carrier.' '.$class; + $a_type['_Name'] = '(Intershipper) '.$carrier.' '.$class; $ret[] = $a_type; } } @@ -381,7 +381,21 @@ return $ret; } - + /** + * Returns virtual field names, that will be saved as properties + * + * @return Array + */ + function GetEngineFields() + { + return Array ( + 'AccountLogin', + 'UPSEnabled', 'UPSAccount', 'UPSInvoiced', 'FDXEnabled', 'FDXAccount', 'FDXInvoiced', + 'DHLEnabled', 'DHLAccount', 'DHLInvoiced', 'USPEnabled', 'USPAccount', 'USPInvoiced', + 'ARBEnabled', 'ARBAccount', 'ARBInvoiced', '1DYEnabled', '2DYEnabled', '3DYEnabled', + 'GNDEnabled', 'ShipMethod', + ); + } } /*$params = Array( Index: units/shipping_quote_engines/shipping_quote_collector.php =================================================================== --- units/shipping_quote_engines/shipping_quote_collector.php (revision 13756) +++ units/shipping_quote_engines/shipping_quote_collector.php (working copy) @@ -17,62 +17,82 @@ function GetShippingQuotes($params) { - if(!$params['dest_city'] || !$params['dest_country'] || - (($params['dest_country'] == 'US' || $params['dest_country'] == 'CA') && !$params['dest_state']) || - !$params['dest_postal'] || !$params['packages']) - { - return Array(); + $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); + /* @var $cs_helper kCountryStatesHelper */ + + $has_states = $cs_helper->CountryHasStates( $cs_helper->getCountryIso($params['dest_country'], true) ); + + if ( + !$params['dest_city'] || !$params['dest_country'] || + ($has_states && !$params['dest_state']) || + !$params['dest_postal'] || !$params['packages'] + ) { + return Array (); } - $db =& $this->Application->GetADODBConnection(); + $cached_var_name = 'ShippingQuotes' . crc32(serialize($params)); - $cached_var_name = 'ShippingQuotes'.crc32(serialize($params)); - $shipping_types = $this->Application->getDBCache($cached_var_name); if ($shipping_types) { return unserialize($shipping_types); } - $sql = 'SELECT Classname FROM '.$this->Application->getUnitOption('sqe', 'TableName').' WHERE Status = 1'; - $classes = $db->GetCol($sql); - $classes[] = 'CustomShippingQuoteEngine'; // always persists $shipping_types = Array(); - foreach($classes as $class) - { + $classes = $this->getEngineClasses(); + + foreach ($classes as $class) { $object =& $this->Application->recallObject($class); + /* @var $object ShippingQuoteEngine */ + $new_shipping_types = $object->GetShippingQuotes($params); $shipping_types = array_merge($shipping_types, $new_shipping_types); } + uasort($shipping_types, Array(&$this, 'price_sort')); - //exclude not available shipping quotes by products + // 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) - { + 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) { + break; + } } - if (!$include) continue; - $available_types[$a_type['ShippingId']] = $a_type; + + if (!$include) { + continue; + } + + $available_types[ $a_type['ShippingId'] ] = $a_type; } + $shipping_types = $available_types; } - //exclude Selected Products Only shipping types, not matching products - $available_types = array(); + // 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; + if (!is_array($limit_types) || !in_array($a_type['ShippingId'], $limit_types)) { + continue; + } } - $available_types[$a_type['ShippingId']] = $a_type; + + $available_types[ $a_type['ShippingId'] ] = $a_type; } + $shipping_types = $available_types; $this->Application->setDBCache($cached_var_name, serialize($shipping_types), 24 * 3600); @@ -82,52 +102,55 @@ function GetAvailableShippingTypes() { - $db =& $this->Application->GetADODBConnection(); - $sql = 'SELECT Classname FROM '.$this->Application->getUnitOption('sqe', 'TableName').' WHERE Status = 1'; - $classes = $db->GetCol($sql); - $classes[] = 'CustomShippingQuoteEngine'; // always persists - $shipping_types = Array(); - foreach($classes as $class) - { + $shipping_types = Array (); + $classes = $this->getEngineClasses(); + + foreach ($classes as $class) { $object =& $this->Application->recallObject($class); + /* @var $object ShippingQuoteEngine */ + $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; + } + function SortShippingTypes($elem1, $elem2) { - if($elem1['_Name'] < $elem2['_Name']) - { - return -1; - } - elseif($elem1['_Name'] > $elem2['_Name']) - { - return 1; - } - else - { + 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 -1; - } - elseif($elem1['TotalCost'] > $elem2['TotalCost']) - { - return 1; - } - else - { + if ($elem1['TotalCost'] == $elem2['TotalCost']) { return 0; } + return $elem1['TotalCost'] < $elem2['TotalCost'] ? -1 : 1; } } \ No newline at end of file Index: units/shipping_quote_engines/shipping_quote_engine.php =================================================================== --- units/shipping_quote_engines/shipping_quote_engine.php (revision 13756) +++ units/shipping_quote_engines/shipping_quote_engine.php (working copy) @@ -13,9 +13,23 @@ defined('FULL_PATH') or die('restricted access!'); -class ShippingQuoteEngine extends kBase { +class ShippingQuoteEngine extends kHelper { /** + * Quote engine specific properties + * + * @var Array + */ + var $properties = Array (); + + function ShippingQuoteEngine() + { + parent::kHelper(); + + $this->initProperties(); + } + + /** * $params = Array( * 'AccountLogin' => 'login', * 'AccountPassword' => 'pass', @@ -136,4 +150,48 @@ { } + + /** + * Returns list of shipping types, that can be selected on product editing page + * + * @return Array + */ + function GetAvailableTypes() + { + return Array (); + + } + + /** + * Returns virtual field names, that will be saved as properties + * + * @return Array + */ + function GetEngineFields() + { + return Array (); + } + + /** + * Loads properties of shipping quote engine + * + */ + function initProperties() + { + $sql = 'SELECT Properties, FlatSurcharge, PercentSurcharge + FROM ' . $this->Application->getUnitOption('sqe', 'TableName') . ' + WHERE LOWER(ClassName) = ' . $this->Conn->qstr( strtolower( get_class($this) ) ); + $data = $this->Conn->GetRow($sql); + + if (is_array($data)) { + $properties = $data['Properties'] ? unserialize($data['Properties']) : Array (); + $properties['FlatSurcharge'] = $data['FlatSurcharge']; + $properties['PercentSurcharge'] = $data['PercentSurcharge']; + + $this->properties = $properties; + } + else { + $this->properties = Array (); + } + } } \ No newline at end of file Index: units/shipping_quote_engines/shipping_quote_engine_event_handler.php =================================================================== --- units/shipping_quote_engines/shipping_quote_engine_event_handler.php (revision 13756) +++ units/shipping_quote_engines/shipping_quote_engine_event_handler.php (working copy) @@ -22,62 +22,46 @@ */ function OnBeforeItemUpdate(&$event) { + parent::OnBeforeItemUpdate($event); + $object =& $event->getObject(); - if($object->GetDBField('AccountPassword') == '') - { - $sql = 'SELECT Properties FROM '.$object->TableName.' - WHERE EngineId = '.$object->GetDBField('EngineId'); - $properties = unserialize( $this->Conn->GetOne($sql) ); - $object->SetDBField('AccountPassword', $properties['AccountPassword']); + /* @var $object kDBItem */ + + $engine =& $this->Application->recallObject( $object->GetDBField('ClassName') ); + /* @var $engine ShippingQuoteEngine */ + + $engine_fields = $engine->GetEngineFields(); + $properties = $object->GetDBField('Properties'); + $properties = $properties ? unserialize($properties) : Array (); + + // common fields for all shipping quote engines + if ($object->GetDBField('AccountPassword') != '') { + // don't erase password by accident + $engine_fields[] = 'AccountPassword'; } - $properties = Array( - 'AccountLogin' => $object->GetDBField('AccountLogin'), - 'AccountPassword' => $object->GetDBField('AccountPassword'), - 'UPSEnabled' => $object->GetDBField('UPSEnabled'), - 'UPSAccount' => $object->GetDBField('UPSAccount'), - 'UPSInvoiced' => $object->GetDBField('UPSInvoiced'), - 'FDXEnabled' => $object->GetDBField('FDXEnabled'), - 'FDXAccount' => $object->GetDBField('FDXAccount'), - 'DHLEnabled' => $object->GetDBField('DHLEnabled'), - 'DHLAccount' => $object->GetDBField('DHLAccount'), - 'DHLInvoiced' => $object->GetDBField('DHLInvoiced'), - 'USPEnabled' => $object->GetDBField('USPEnabled'), - 'USPAccount' => $object->GetDBField('USPAccount'), - 'USPInvoiced' => $object->GetDBField('USPInvoiced'), - 'ARBEnabled' => $object->GetDBField('ARBEnabled'), - 'ARBAccount' => $object->GetDBField('ARBAccount'), - 'ARBInvoiced' => $object->GetDBField('ARBInvoiced'), - '1DYEnabled' => $object->GetDBField('1DYEnabled'), - '2DYEnabled' => $object->GetDBField('2DYEnabled'), - '3DYEnabled' => $object->GetDBField('3DYEnabled'), - 'GNDEnabled' => $object->GetDBField('GNDEnabled'), - 'ShipMethod' => $object->GetDBField('ShipMethod'), - ); - $properties = serialize($properties); - $object->SetDBField('Properties', $properties); + // save shipping quote specific fields + foreach ($engine_fields as $engine_field) { + $properties[$engine_field] = $object->GetDBField($engine_field); + } + + $object->SetDBField('Properties', serialize($properties)); + + $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); + /* @var $cs_helper kCountryStatesHelper */ + $from_country = $this->Application->ConfigValue('Comm_Shipping_Country'); - if (strlen($from_country) == 3) { - $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); - /* @var $cs_helper kCountryStatesHelper */ + $has_states = strlen($from_country) == 3 ? $cs_helper->CountryHasStates($from_country) : false; - // get 2symbol ISO code from 3symbol ISO code - $from_country = $cs_helper->getCountryIso($from_country); - } + $valid_address = $from_country && ($has_states && $this->Application->ConfigValue('Comm_Shipping_State') || !$has_states) && + $this->Application->ConfigValue('Comm_Shipping_City') && $this->Application->ConfigValue('Comm_Shipping_ZIP'); - if( !function_exists('curl_init') ) - { - $object->FieldErrors['Status']['pseudo'] = 'curl_not_present'; - $object->ErrorMsgs['curl_not_present'] = $this->Application->Phrase('la_error_EnableCurlFirst'); + if (!function_exists('curl_init')) { + $object->SetError('Status', 'curl_not_present'); } - elseif( $object->GetDBField('Status') == 1 && (!$this->Application->ConfigValue('Comm_Shipping_City') || !$from_country || - ( ($from_country == 'US' || $from_country == 'CA') && !$this->Application->ConfigValue('Comm_Shipping_State') ) || - !$this->Application->ConfigValue('Comm_Shipping_ZIP') ) ) - { - $object->FieldErrors['Status']['pseudo'] = 'from_info_not_filled_in'; - $object->ErrorMsgs['from_info_not_filled_in'] = $this->Application->Phrase('la_error_FillInShippingFromAddress'); + elseif (($object->GetDBField('Status') == STATUS_ACTIVE) && !$valid_address) { + $object->SetError('Status', 'from_info_not_filled_in'); } - } /** @@ -97,35 +81,68 @@ } /** - * Enter description here... + * Sets virtual fields from serialized properties array * * @param kEvent $event */ function OnAfterItemLoad(&$event) { + parent::OnAfterItemLoad($event); + $object =& $event->getObject(); - $properties = unserialize( $object->GetDBField('Properties') ); - $object->SetDBFieldsFromHash($properties); + /* @var $object kDBItem */ + + $properties = $object->GetDBField('Properties'); + + if ($properties) { + $object->SetDBFieldsFromHash( unserialize($properties) ); + } } + /** + * Deletes cached shipping quotes on any setting change + * + * @param kEvent $event + */ function OnAfterItemCreate(&$event) { - $event->CallSubEvent('OnAnyChange'); + parent::OnAfterItemCreate($event); + + $this->_deleteQuoteCache(); } + /** + * Deletes cached shipping quotes on any setting change + * + * @param kEvent $event + */ function OnAfterItemUpdate(&$event) { - $event->CallSubEvent('OnAnyChange'); + parent::OnAfterItemUpdate($event); + + $this->_deleteQuoteCache(); } + /** + * Deletes cached shipping quotes on any setting change + * + * @param kEvent $event + */ function OnAfterItemDelete(&$event) { - $event->CallSubEvent('OnAnyChange'); + parent::OnAfterItemDelete($event); + + $this->_deleteQuoteCache(); } - function OnAnyChange(&$event) + /** + * Deletes cached shipping quotes + * + */ + function _deleteQuoteCache() { - $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Cache WHERE VarName LIKE "ShippingQuotes%"'; + $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Cache + WHERE VarName LIKE "ShippingQuotes%"'; $this->Conn->Query($sql); } } \ No newline at end of file Index: units/shipping_quote_engines/shipping_quote_engines_config.php =================================================================== --- units/shipping_quote_engines/shipping_quote_engines_config.php (revision 13756) +++ units/shipping_quote_engines/shipping_quote_engines_config.php (working copy) @@ -21,9 +21,9 @@ 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), 'RegisterClasses' => Array ( Array ('pseudo' => 'ShippingQuoteEngine', 'class' => 'ShippingQuoteEngine', 'file' => 'shipping_quote_engine.php', 'build_event' => ''), - Array ('pseudo' => 'CustomShippingQuoteEngine', 'class' => 'CustomShippingQuoteEngine', 'file' => 'custom_shipping_quote_engine.php', 'build_event' => ''), - Array ('pseudo' => 'Intershipper', 'class' => 'Intershipper', 'file' => 'intershipper.php', 'build_event' => ''), - Array ('pseudo' => 'USPS', 'class' => 'USPS', 'file' => 'usps.php', 'build_event' => ''), + Array ('pseudo' => 'CustomShippingQuoteEngine', 'class' => 'CustomShippingQuoteEngine', 'file' => 'custom_shipping_quote_engine.php', 'require_classes' => 'ShippingQuoteEngine', 'build_event' => ''), + Array ('pseudo' => 'Intershipper', 'class' => 'Intershipper', 'file' => 'intershipper.php', 'require_classes' => 'ShippingQuoteEngine', 'build_event' => ''), + Array ('pseudo' => 'USPS', 'class' => 'USPS', 'file' => 'usps.php', 'require_classes' => 'ShippingQuoteEngine', 'build_event' => ''), Array ('pseudo' => 'ShippingQuoteCollector', 'class' => 'ShippingQuoteCollector', 'file' => 'shipping_quote_collector.php', 'build_event' => '', 'require_classes' => 'ShippingQuoteEngine'), ), 'AutoLoad' => true, @@ -93,8 +93,12 @@ 'PercentSurcharge' => Array ('type' => 'double', 'not_null' => 1, 'default' => '0'), 'Status' => Array ( 'type' => 'int', - 'formatter' => 'kOptionsFormatter', - 'options' => Array ( 1 => 'la_Enabled', 0 => 'la_Disabled' ), 'use_phrases' => 1, + 'formatter' => 'kOptionsFormatter', + 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, + 'error_msgs' => Array ( + 'curl_not_present' => '!la_error_EnableCurlFirst!', + 'from_info_not_filled_in' => '!la_error_FillInShippingFromAddress!', + ), 'default' => 0, 'not_null' => 1, ), 'Properties' => Array ('type' => 'string', 'default' => NULL), Index: units/shipping_quote_engines/usps.php =================================================================== --- units/shipping_quote_engines/usps.php (revision 13756) +++ units/shipping_quote_engines/usps.php (working copy) @@ -53,7 +53,6 @@ var $types = Array(); var $intl_types = Array(); - function USPS() { parent::kBase(); @@ -747,7 +746,6 @@ // parse response - $xml_helper =& $this->Application->recallObject('kXMLHelper'); /* @var $xml_helper kXMLHelper */ @@ -1090,10 +1088,6 @@ return Array('error' => implode('
', $errors)); } - - - - $xml_helper =& $this->Application->recallObject('kXMLHelper'); $root_node =& $xml_helper->Parse($body); /* @var $root_node kXMLNode */ @@ -1193,4 +1187,13 @@ return strip_tags($value); } + /** + * Returns virtual field names, that will be saved as properties + * + * @return Array + */ + function GetEngineFields() + { + return Array ('AccountLogin'); + } } \ No newline at end of file