Post by firegazer » Tue Oct 30, 2012 2:33 am

I had to write a custom shipping API for CanPar a while back. I'm almost positive that I tested it thoroughly on both guest and logged checkout, but it's possible that it broke in between updates. We are currently on version 1.5.3.1.

While logged in, the API works just fine. On guest checkout, for some odd reason, it throws an error as below:
Fatal error: Call to a member function getAttribute() on a non-object in /home/SITENAME/public_html/catalog/model/shipping/canpar.php on line 88
In the error log, it looks like this:
2012-10-29 14:22:59 - PHP Warning: DOMDocument::loadXML() [<a href='domdocument.loadxml'>domdocument.loadxml</a>]: Start tag expected, '<' not found in Entity, line: 1 in /home/SITENAME/public_html/catalog/model/shipping/canpar.php on line 80
I find it bizarre that the system would suddenly discover a syntax error in the same file ONLY while in guest checkout mode. Does anyone have a better idea of what might be doing this?

P.S. The CanPar model file is below. I make no promises as to its beauty or efficiency, since I am only an API programmer by occasional necessity.

Code: Select all

<?php
class ModelShippingCanpar extends Model {
	private $name = '';
	
	function getQuote($address) {
		$this->name = 'canpar';
		$this->load->language('shipping/' . $this->name);
		
		if ($this->config->get($this->name . '_status')) {

			$country = (int)$address['country_id'];
			
			if ($country == 38) {
				$status = TRUE;
			} else {
				$status = FALSE;
			}
        } else {
            $status = FALSE;
        }
		
		$method_data = array();
		
		if ($status) {
			$postcode = str_replace(' ', '', $address['postcode']);
			$weight = ($this->cart->getWeight() == '0') ? '0.1' : $this->cart->getWeight();

			$weight = str_replace(',','',$this->weight->convert($weight, $this->config->get('config_weight_class_id'), 1));
			$weight = round($weight,4);
			
			$xml  = '<shipment ';
			$xml .= 'shipper_number="' . $this->config->get($this->name . '_shipper_number') . '" ';
			$xml .= 'destination_postal_code="' . $postcode . '" ';
			$xml .= 'service_type="1" put="0" weight_system="METRIC" dimentional_system="METRIC" ';
			$xml .= 'language="en"';
			$xml .= '>';  
			$xml .= '	<total '; 
				$xml .= 'total_pieces="1" total_weight="' . $weight . '" '; 
				$xml .= 'total_cod="0" total_dv="0" total_xc="0"';
				$xml .= ' />';
			$xml .= '</shipment>';
							
			
			$qstring = 'shipment=' . urlencode($xml) . '&token=' . $this->config->get($this->name . '_token');
			$url = 'https://www.canpar.com/XML/RatingXML.jsp';
			
				set_time_limit(5);
				$ch = curl_init();
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
				curl_setopt($ch, CURLOPT_URL, $url . '?' . $qstring);
				curl_setopt($ch, CURLOPT_POST, 1);  
				curl_setopt($ch, CURLOPT_TIMEOUT, 60);  
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
				curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
				curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2678400);
				curl_setopt($ch, CURLOPT_HEADER, 0);
				curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
				
				$result = "";
				$result = curl_exec($ch);

				if ($this->config->get($this->name . '_debug')) {
					$this->log->write("CANPAR CURL DATA SENT: " . urldecode($xml));
					$this->log->write("CANPAR CURL DATA RECV: " . $result);
				}

				// Check if any error occured
				$curl_err = '';
				if(curl_errno($ch)) {
					//echo('Curl error: ' . curl_error($ch));
					return $this->retError('Curl error: ' . curl_error($ch));
				}
				curl_close ($ch);
			
			$quote_data = array();
			
			if($result){
			$dom = new DOMDocument('1.0', 'UTF-8');
					$dom->loadXml($result);

					$rate_response = $dom->getElementsByTagName('rate')->item(0);
					$error = $dom->getElementsByTagName('error')->item(0);
					if($error){
						$error_message = $error->getAttribute('error_type');
						return $this->retError($error_message);
						}
					$totalrate = $rate_response->getAttribute('total_charge');
			}
			else{
				return $this->retError();
			}
						
			$cost = $this->currency->convert($totalrate, 'CAD', $this->config->get('config_currency'));
			
			$quote_data[$this->name] = array(
								'code'         => 'canpar.' . $this->name,
								'title'        => 'Canpar ' . '(No P.O. Boxes, please.)',
								'cost'         => $cost,
								'tax_class_id' => 0,
								'text'         => $this->currency->format($this->tax->calculate($this->currency->convert($totalrate, $this->config->get('config_currency'), $this->currency->getCode()), 0, $this->config->get('config_tax')))
							);
			
			$title = $this->language->get('text_title');
		
			$method_data = array(
				'code'       => 'canpar',
				'title'      => $title,
				'quote'      => $quote_data,
				'sort_order' => 2,
				'error'      => false
			);
		}
		
		return $method_data;
	}
	
function retError($error="unknown error") {
    	$quote_data = array();

      	$quote_data['' . $this->name] = array(
			'code'         => $this->name . '.' . $this->name, //v15x
        	'title'        => $this->language->get('text_title'),
			'cost'         => NULL,
         	'tax_class_id' => NULL,
			'text'         => 'ERROR: ' . $error
      	);

    	$method_data = array(
		  'code'         => $this->name, //v15x
		  'title'        => $this->language->get('text_title'),
		  'quote'        => $quote_data,
		  'sort_order'   => 2,
		  'tax_class_id' => 0,
		  'error'        => $error
		);
		return $method_data;
	}
}
?>

Newbie

Posts

Joined
Thu Sep 29, 2011 6:44 am

Post by firegazer » Wed Oct 31, 2012 3:30 am

Fixed as of this morning. I can't say exactly what it was, but it was certainly address-related. I spent some time implementing small fixes to known issues, and I think it may have had to do with either the new company_id and tax_id.

Newbie

Posts

Joined
Thu Sep 29, 2011 6:44 am
Who is online

Users browsing this forum: No registered users and 5 guests