Post by head_dunce » Wed May 01, 2019 5:31 am

What I am going to do is have the function take the order information and use curl to post it to another application (a Perl application I wrote.) Similar to what Yahoo does here - https://help.smallbusiness.yahoo.net/s/article/SLN19411
So I have an event trigger set up -

Code: Select all

INSERT INTO `oc_event` (`code`, `trigger`, `action`, `status`) VALUES ('post_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/post_order/post_order_data', 1);
And this file -
/var/www/html/catalog/controller/extension/module/post_order.php

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function post_order_data() {
		file_put_contents('/var/www/html/test.txt', 'Test');

	}
}
And that works, when an order is placed, the text file is written to, so I'm getting somewhere.
What I don't understand is what variables are available to the function? Or how to load them? Or..?

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by straightlight » Wed May 01, 2019 5:41 am

Code: Select all

INSERT INTO `oc_event` (`code`, `trigger`, `action`, `status`) VALUES ('my_module', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/post_order/post_order_data', 1);
Unnecessary. Rather use:

Code: Select all

$this->load->model('setting/event');

$this->model_setting_event->addEvent('post_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/post_order/postOrderData');
In your installation method from the admin controller.

And since it's an after event, replace:

Code: Select all

public function post_order_data() {
with:

Code: Select all

public function postOrderData(&$route, &$args, &$output) {
Last edited by straightlight on Wed May 01, 2019 9:01 am, edited 1 time in total.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by head_dunce » Wed May 01, 2019 8:28 am

Unnecessary. Rather use:

Code: Select all

$this->load->model('setting/event');

$this->model_setting_event->addEvent('post_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/post_order/post_order_data');
Yeah, I get that, but I don't want to make an install file before I even know what I'm installing. In the end, isn't it the same? Unless of course you plan on distributing the code.
--------------------
And since it's an after event, replace:

Code: Select all

public function post_order_data() {
with:

Code: Select all

public function post_order_data(&$route, &$args, &$output) {
So those are always the vars? Is there anywhere that defines what's in those vars? I tried to var_dump those into the file, but hit a bunch of errors in trying (I'm new to PHP so please bear with me.) It was the end of the day so I posted here hoping to get better direction. Thank you for the help

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by straightlight » Wed May 01, 2019 8:47 am

So those are always the vars? Is there anywhere that defines what's in those vars? I tried to var_dump those into the file, but hit a bunch of errors in trying (I'm new to PHP so please bear with me.) It was the end of the day so I posted here hoping to get better direction. Thank you for the help
Please provide those error messages; forum rules.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by straightlight » Wed May 01, 2019 9:02 am

I have also modified the steps above as I just realized the underscores to call a method in OC may not load the event either.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by head_dunce » Wed May 01, 2019 9:20 am

straightlight wrote:
Wed May 01, 2019 8:47 am
So those are always the vars? Is there anywhere that defines what's in those vars? I tried to var_dump those into the file, but hit a bunch of errors in trying (I'm new to PHP so please bear with me.) It was the end of the day so I posted here hoping to get better direction. Thank you for the help
Please provide those error messages; forum rules.
Oddly came up with json errors last I remember. Will dive back into the code tomorrow and post more. At least I know I'm heading the right direction. Sad there isn't more doc on this, hopefully this post can help others in the future. Starting to really question moving to OC at this point.

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by head_dunce » Wed May 01, 2019 9:23 am

straightlight wrote:
Wed May 01, 2019 9:02 am
I have also modified the steps above as I just realized the underscores to call a method in OC may not load the event either.
Yeah, found out underscores act weird in this the hard way too. You don't want to use them in the controller extension or it won't find it.

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by head_dunce » Wed May 01, 2019 10:22 pm

Ok, found out that the var_dump needed to be done capturing the output buffer to work, so like this -

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function post_order_data(&$route, &$args, &$output) {

		ob_start();
		var_dump($route);
		$dump_route = ob_get_clean();

		ob_start();
		var_dump($args);
		$dump_args = ob_get_clean();

		ob_start();
		var_dump($output);
		$dump_output = ob_get_clean();

		$data_dump = "ROUTE:\n$dump_route\n\nARGS:\n$dump_args\n\nOUTPUT:\n$dump_output\n\n";

		file_put_contents('/var/www/html/test.txt',  $data_dump );

	}
}
But that's not really giving me anything because the file just has

Code: Select all

[root@opencart html]# cat test.txt
ROUTE:
string(30) "checkout/order/addOrderHistory"


ARGS:
array(2) {
  [0]=>
  int(16)
  [1]=>
  string(1) "1"
}


OUTPUT:
NULL



Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by head_dunce » Wed May 01, 2019 10:33 pm

Ok, so now I see that the $args has the order number in position 0 but I don't know what position 1 is for yet? Is there no where that defines this?

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by head_dunce » Wed May 01, 2019 11:10 pm

Ok, if I dump $this I get a whole mess of information, but... doesn't seem like the right way to do it

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function post_order_data(&$route, &$args, &$output) {

		ob_start();
		var_dump($route);
		$dump_route = ob_get_clean();

		ob_start();
		var_dump($args);
		$dump_args = ob_get_clean();

		ob_start();
		var_dump($output);
		$dump_output = ob_get_clean();

		ob_start();
		var_dump($this);
		$dump_this = ob_get_clean();

		$data_dump = "ROUTE:\n$dump_route\n\nARGS:\n$dump_args\n\nOUTPUT:\n$dump_output\n\nTHIS:\n$dump_this\n\n";

		file_put_contents('/var/www/html/test.txt',  $data_dump );

	}
}

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by straightlight » Wed May 01, 2019 11:56 pm

No, it's not. Simply troubleshoot it this way:

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function postOrderData(&$route, &$args, &$output) {
		$this->log->write('Route: ' . $route .', Args: ' . print_r($args) . ', Output: ' . $output . '.');
	}
}
Then, check your error logs in the OC admin or in your storage/logs folder.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by head_dunce » Thu May 02, 2019 12:07 am

straightlight wrote:
Wed May 01, 2019 11:56 pm
No, it's not. Simply troubleshoot it this way:

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function postOrderData(&$route, &$args, &$output) {
		$this->log->write('Route: ' . $route .', Args: ' . print_r($args) . ', Output: ' . $output . '.');
	}
}
Then, check your error logs in the OC admin or in your storage/logs folder.
That's going to give me the same info as I already got from dumping those vars though, so no difference. What I want to know is how do I get the order information? Can I get the information from $this or do I really need to hit the db again?

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function post_order_data(&$route, &$args, &$output) {
		$order_id = $args[0];
		$this->load->model('checkout/order');
		$orderinfo = $this->model_checkout_order->getOrder($order_id);

		ob_start();
		var_dump($orderinfo);
		$dump_getorder = ob_get_clean();

		file_put_contents('/var/www/html/test.txt',  $dump_getorder );

	}
}

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by straightlight » Thu May 02, 2019 12:20 am

You are still using the underscore with the method so not sure which method name you are using now …

However, you could use the same example as already queried for the order ID in the catalog/controller/event/activity.php file under the addOrderHistory method.

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function postOrderData(&$route, &$args, &$output) {
		$this->load->model('checkout/order');
			
		$order_info = $this->model_checkout_order->getOrder($args[0]);

		if ($order_info) {
		     // Your argument here ...
		}
	}
}

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by head_dunce » Thu May 02, 2019 4:30 am

straightlight wrote:
Thu May 02, 2019 12:20 am
You are still using the underscore with the method so not sure which method name you are using now …

However, you could use the same example as already queried for the order ID in the catalog/controller/event/activity.php file under the addOrderHistory method.
Ok, so here's what I've changed and tried.

Using this for the event -

Code: Select all

INSERT INTO `oc_event` (`code`, `trigger`, `action`, `status`) VALUES ('post_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/post_order/postorderdata', 1);
And this for the function -

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function postOrderData(&$route, &$args, &$output) {

		ob_start();
		var_dump($route);
		$dump_route = ob_get_clean();

		ob_start();
		var_dump($args);
		$dump_args = ob_get_clean();

		ob_start();
		var_dump($output);
		$dump_output = ob_get_clean();

		ob_start();
		var_dump($this);
		$dump_this = ob_get_clean();

		$data_dump = "ROUTE:\n$dump_route\n\nARGS:\n$dump_args\n\nOUTPUT:\n$dump_output\n\nTHIS:\n$dump_this\n\n";

		//$order_id = $args[0];
		//$this->load->model('checkout/order');
		//$orderinfo = $this->model_checkout_order->getOrder($order_id);

		//ob_start();
		//var_dump($orderinfo);
		//$data_dump = ob_get_clean();

		file_put_contents('/var/www/html/test.txt',  $data_dump );

	}
}
Everything works. The only change above is I took out the underscores in the function name. I know I can call the commented out section in that function and it returns the order info, but I also see that the order info is already in the variable $this so it seems really sloppy to do another call to retrieve the information that is already in $this. I'm hoping I can retrieve that information without making another call?

If I'm understanding your other comment right, I tried changing

Code: Select all

INSERT INTO `oc_event` (`code`, `trigger`, `action`, `status`) VALUES ('post_order', 'catalog/model/checkout/order/addOrderHistory/after', 'extension/module/post_order/postorderdata', 1);
To this

Code: Select all

INSERT INTO `oc_event` (`code`, `trigger`, `action`, `status`) VALUES ('post_order', 'catalog/controller/event/activity/addOrderHistory/after', 'extension/module/post_order/postorderdata', 1);
And I also tried

Code: Select all

INSERT INTO `oc_event` (`code`, `trigger`, `action`, `status`) VALUES ('post_order', 'catalog/controller/event/activity/addOrderHistory/before', 'extension/module/post_order/postorderdata', 1);
But both of those different events didn't seem to do anything, so maybe I'm just not understanding what you're trying to explain?

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by straightlight » Thu May 02, 2019 4:32 am

Code: Select all

extension/module/post_order/postorderdata
for:

Code: Select all

extension/module/post_order/postOrderData
Instruction unfollowed. If you are not sure how to set-up an event, you can always create a new service request in the Commercial Support section of the forum to get this done as a custom job.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by head_dunce » Thu May 02, 2019 4:47 am

straightlight wrote:
Thu May 02, 2019 4:32 am

Code: Select all

extension/module/post_order/postorderdata
for:

Code: Select all

extension/module/post_order/postOrderData
Instruction unfollowed. If you are not sure how to set-up an event, you can always create a new service request in the Commercial Support section of the forum to get this done as a custom job.
I tried it both ways, capitalization didn't matter. Not sure why I'd have to hire someone to answer if there's a proper way to retrieve the data. I've been programming for many years... way way back to BAL and JCL mainframes. No need to get snotty. Thanks for trying to help.

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by straightlight » Thu May 02, 2019 4:50 am

I've been programming for many years... way way back to BAL and JCL mainframes.
In this case, it should be no problem for you to figure how to activate this custom event. :)

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by head_dunce » Thu May 02, 2019 4:53 am

straightlight wrote:
Thu May 02, 2019 4:50 am
I've been programming for many years... way way back to BAL and JCL mainframes.
In this case, it should be no problem for you to figure how to activate this custom event. :)
Yeah, if there was doc on it I wouldn't be here asking. Not sure why you're trolling. Have a good day sir.

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by head_dunce » Thu May 02, 2019 5:47 am

So I see all the order information is not passed in $this, looks like it's missing items and options. Since the order information is assembled in the function addOrderHistory located in /var/www/html/catalog/model/checkout/order.php and this trigger happens after that function, those variables (items/options) die at the end of the function. So they have to be re-queried for the function that happens via the event trigger. The only way around that would be to change the file order.php to edit inside of the addOrderHistory function to capture that info before the function exits.

It does seem strange that the order information / products / options aren't built into one large data structure and passed around with a reference, but from what I can see so far, that doesn't seem to be the case. If anyone knows otherwise, or another location to put the event trigger that may have that info passed, please enlighten me.

Here's where I'm leaving off for today. Simple enough. I'll have to assemble the data to pass via curl next so it operates as the Yahoo code does so I can mimick this https://help.smallbusiness.yahoo.net/s/article/SLN19411
Thanks for the help

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function postOrderData(&$route, &$args, &$output) {

		//ob_start();
		//var_dump($route);
		//$dump_route = ob_get_clean();

		//ob_start();
		//var_dump($args);
		//$dump_args = ob_get_clean();

		//ob_start();
		//var_dump($output);
		//$dump_output = ob_get_clean();

		//ob_start();
		//var_dump($this);
		//$dump_this = ob_get_clean();

		//$data_dump = "ROUTE:\n$dump_route\n\nARGS:\n$dump_args\n\nOUTPUT:\n$dump_output\n\nTHIS:\n$dump_this\n\n";

		$order_id = $args[0];
		$this->load->model('checkout/order');
		$order_info = $this->model_checkout_order->getOrder($order_id);

		ob_start();
		var_dump($order_info);
		$data_dump = ob_get_clean();
		$data_dump .= "\n----------------------------\n";

		// only shows customer info if customer uses or creates a registered account
		$this->load->model('account/customer');
		$customer_info = $this->model_account_customer->getCustomer($order_info['customer_id']);
		ob_start();
		var_dump($customer_info);
		$data_dump .= ob_get_clean();
		$data_dump .= "\n----------------------------\n";

		$order_products = $this->model_checkout_order->getOrderProducts($order_id);
		foreach ($order_products as $order_product) {

			ob_start();
			var_dump($order_product);
			$data_dump .= ob_get_clean();
			$data_dump .= "\n----------------------------\n";

			$order_options = $this->model_checkout_order->getOrderOptions($order_id, $order_product['order_product_id']);
			ob_start();
			var_dump($order_options);
			$data_dump .= ob_get_clean();
			$data_dump .= "\n----------------------------\n";
		}

		file_put_contents('/var/www/html/test.txt',  $data_dump );

	}
}

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm

Post by head_dunce » Wed May 08, 2019 4:42 am

An update if anyone else is looking for real time order posting in the Yahoo Merchant Solutions format. I haven't set up the cc processing yet in OC, so those aren't in this code yet.

Code: Select all

<?php
class ControllerExtensionModulePostOrder extends Controller {
	public function postOrderData(&$route, &$args, &$output) {

		$order_id = $args[0];
		$this->load->model('checkout/order');
		$order_info = $this->model_checkout_order->getOrder($order_id);

		$order = '';
		$order['ID'] = $order_id;
		$order['IP'] =  $order_info['ip'];
		$order['Date'] =  $order_info['date_added'];
		$order['Numeric-Time'] = $order_info['date_added']; // convert this to epoch

		$order['Space-Id'] =  ''; // does not seem to be defined with Yahoo either
		$order['Store-Id'] =  $order_info['store_id'];
		$order['Store-Name'] =  $order_info['store_name'];

		$order['Ship-Firstname'] = $order_info['shipping_firstname'];
		$order['Ship-Lastname'] = $order_info['shipping_lastname'];
		$order['Ship-Name'] = $order_info['shipping_firstname']." ".$order_info['shipping_lastname'];
		$order['Ship-Company'] =  $order_info['shipping_company'];
		$order['Ship-Address1'] =  $order_info['shipping_address_1'];
		$order['Ship-Address2'] =  $order_info['shipping_address_2'];
		$order['Ship-City'] =  $order_info['shipping_city'];
		$order['Ship-State'] =  $order_info['shipping_zone_code'];
		$order['Ship-Zip'] =  $order_info['shipping_postcode'];
		$order['Ship-Country'] =  $order_info['shipping_country'];
		$order['Ship-Phone'] =  $order_info['telephone'];
		$order['Bill-Firstname'] =  $order_info['payment_firstname'];
		$order['Bill-Lastname'] =  $order_info['payment_lastname'];
		$order['Bill-Name'] = $order_info['payment_firstname']." ".$order_info['payment_lastname'];
		$order['Bill-Company'] =  $order_info['payment_company'];
		$order['Bill-Address1'] =  $order_info['payment_address_1'];
		$order['Bill-Address2'] =  $order_info['payment_address_2'];
		$order['Bill-City'] =  $order_info['payment_city'];
		$order['Bill-State'] =  $order_info['payment_zone_code'];
		$order['Bill-Zip'] =  $order_info['payment_postcode'];
		$order['Bill-Country'] =  $order_info['payment_country'];
		$order['Bill-Phone'] =  $order_info['telephone'];
		$order['Bill-Email'] =  $order_info['email'];

		$order_totals = $this->model_checkout_order->getOrderTotals($order_id);
		foreach ($order_totals as $order_total){
			switch ( $order_total['code'] ){
				case "sub_total" :
					break;
				case "shipping" :
					$order['Shipping-Charge'] =  $order_total['value'];
					break;
				case "coupon" :
					$order['Coupon-Id'] =  $order_total['title']; // name of coupon code
					$order['Coupon-Description'] =  $order_total['title']; // explain coupon - needs updating
					$order['Coupon-Value'] =  $order_total['value'];
					break;
				case "total" :
					$order['Total'] =  $order_total['value'];
					break;
				case "tax" :
					$order['Tax-Charge'] = $order_total['value'];
					break;
			}
		}
		
		$order['Shipping'] =  $order_info['shipping_method'];
		$order['Comments'] =  $order_info['comment'];

//		$order['Gift-Wrap-Message'] =  $order_info[''];

//		$order['Card-Expiry'] =  $order_info[''];
//		$order['Card-Name'] =  $order_info[''];
//		$order['Card-Number'] =  $order_info[''];
//		$order['CardAuth-Amount'] =  $order_info[''];
//		$order['CardAuth-Approval-Number'] =  $order_info[''];
//		$order['CardAuth-Auth-Response'] =  $order_info[''];
//		$order['CardAuth-Avs-Response'] =  $order_info[''];
//		$order['CardAuth-Cvc2-Response'] =  $order_info[''];
            
		$order['Entry-Point'] =  ""; // Yahoo would put in first page user came to site on, not a stock option on OC
		$order['Referer'] =  ""; // Yahoo would put in the referer, not a stock option on OC
     
		$itemcount = 1;
		$order_products = $this->model_checkout_order->getOrderProducts($order_id);
		foreach ($order_products as $order_product) {

			$order['Item-Code-'.$itemcount] =  $order_product['model'];
			$order['Item-Id-'.$itemcount] =  $order_product['product_id']; // Yahoo would have this be the page ID
			$order['Item-Description-'.$itemcount] =  $order_product['name'];
			$order['Item-Quantity-'.$itemcount] =  $order_product['quantity'];
			$order['Item-Unit-Price-'.$itemcount] =  $order_product['price'];

			$order['Item-Taxable-'.$itemcount] =  "YES"; // OC has an option for tax class on the product that could be looked up, just putting YES for now
	
			$order['Item-Thumb-'.$itemcount] =  ""; // Yahoo would give the thumbnail image of the product, would have to be looked up in OC
			$order['Item-Url-'.$itemcount] = ""; // Yahoo would put in the url to the item here

			$order_options = $this->model_checkout_order->getOrderOptions($order_id, $order_product['order_product_id']);
			foreach ($order_options as $order_option){
				$optionname = 'Item-Option-'.$itemcount.'-'.$order_option['name'];
				$order[$optionname] = $order_option['value'];
			}


			$itemcount++;
		}
		$order['Item-Count'] =  $itemcount - 1;

		// Send the data via post to another location via curl

		$curl_error_msg = '';

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL,"http://<YourURLtoPostTo>");
		curl_setopt($ch, CURLOPT_POST, 1);
		$curlpostfields = http_build_query(array($order));
		curl_setopt($ch, CURLOPT_POSTFIELDS, $curlpostfields);   

		curl_setopt($ch, CURLOPT_FAILONERROR, true);

		curl_exec($ch);
		if (curl_error($ch)) {
			$curl_error_msg = curl_error($ch);
		}

		curl_close($ch);

		// Not sure what to do when there is an error with curl, send email? Store in DB and retry? TBD for now.

	}
}

Jim
https://www.carguygarage.com
Yahoo Store since 2006 moved to OpenCart on January 24, 2020


Active Member

Posts

Joined
Thu Apr 04, 2019 11:50 pm
Who is online

Users browsing this forum: No registered users and 143 guests