Version Description
- First release
=
Download this release
Release Info
Developer | printful |
Plugin | Printful Integration for WooCommerce |
Version | 1.0 |
Comparing to | |
See all releases |
Version 1.0
- PrintfulClient.php +177 -0
- printful-shipping.php +152 -0
- readme.txt +46 -0
PrintfulClient.php
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This class helps to use the Printful API
|
4 |
+
*
|
5 |
+
* Requires PHP version 5, JSON and CURL extensions
|
6 |
+
*
|
7 |
+
* @package Printful
|
8 |
+
* @version 1.0
|
9 |
+
* @copyright 2014 Idea Bits LLC
|
10 |
+
*/
|
11 |
+
|
12 |
+
class PrintfulClient {
|
13 |
+
private $key = false;
|
14 |
+
private $lastResponseRaw;
|
15 |
+
private $lastResponse;
|
16 |
+
|
17 |
+
const API_URL = 'https://api.theprintful.com/';
|
18 |
+
const USER_AGENT = 'Printful API WooCommerce Library 1.0';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param string $key Printful Store API key
|
22 |
+
* @throws PrintfulException if the library failed to initialize
|
23 |
+
*/
|
24 |
+
public function __construct($key = ''){
|
25 |
+
$key = (string)$key;
|
26 |
+
|
27 |
+
if(!function_exists('json_decode') || !function_exists('json_encode')){
|
28 |
+
throw new PrintfulException('PHP JSON extension is required for the Printful API library to work!');
|
29 |
+
}
|
30 |
+
if(!function_exists('curl_init') ){
|
31 |
+
throw new PrintfulException('PHP CURL extension is required for the Printful API library to work!');
|
32 |
+
}
|
33 |
+
if(strlen($key) < 32){
|
34 |
+
throw new PrintfulException('Missing or invalid Printful store key!');
|
35 |
+
}
|
36 |
+
$this->key = $key;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Returns total available item count from the last request if it supports paging (e.g order list) or null otherwise.
|
41 |
+
*
|
42 |
+
* @return int|null Item count
|
43 |
+
*/
|
44 |
+
public function getItemCount(){
|
45 |
+
return isset($this->lastResponse['paging']['total']) ? $this->lastResponse['paging']['total'] : null;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Perform a GET request to the API
|
50 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
51 |
+
* @param array $params Additional GET parameters as an associative array
|
52 |
+
* @return mixed API response
|
53 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
54 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
55 |
+
*/
|
56 |
+
public function get($path, $params = array()){
|
57 |
+
return $this->request('GET', $path, $params);
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Perform a DELETE request to the API
|
62 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
63 |
+
* @param array $params Additional GET parameters as an associative array
|
64 |
+
* @return mixed API response
|
65 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
66 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
67 |
+
*/
|
68 |
+
public function delete($path, $params = array()){
|
69 |
+
return $this->request('DELETE', $path, $params);
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Perform a POST request to the API
|
74 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
75 |
+
* @param array $data Request body data as an associative array
|
76 |
+
* @param array $params Additional GET parameters as an associative array
|
77 |
+
* @return mixed API response
|
78 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
79 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
80 |
+
*/
|
81 |
+
public function post($path, $data = array(), $params = array()){
|
82 |
+
return $this->request('POST', $path, $params, $data);
|
83 |
+
}
|
84 |
+
/**
|
85 |
+
* Perform a PUT request to the API
|
86 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
87 |
+
* @param array $data Request body data as an associative array
|
88 |
+
* @param array $params Additional GET parameters as an associative array
|
89 |
+
* @return mixed API response
|
90 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
91 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
92 |
+
*/
|
93 |
+
public function put($path, $data = array(), $params = array()){
|
94 |
+
return $this->request('PUT', $path, $params, $data);
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Return raw response data from the last request
|
99 |
+
* @return string|null Response data
|
100 |
+
*/
|
101 |
+
public function getLastResponseRaw(){
|
102 |
+
return $this->lastResponseRaw;
|
103 |
+
}
|
104 |
+
/**
|
105 |
+
* Return decoded response data from the last request
|
106 |
+
* @return array|null Response data
|
107 |
+
*/
|
108 |
+
public function getLastResponse(){
|
109 |
+
return $this->lastResponse;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Internal request implementation
|
114 |
+
*/
|
115 |
+
private function request($method, $path, array $params = array(), $data = null){
|
116 |
+
|
117 |
+
$this->lastResponseRaw = null;
|
118 |
+
$this->lastResponse = null;
|
119 |
+
|
120 |
+
$url = trim($path,'/');
|
121 |
+
|
122 |
+
if(!empty($params)){
|
123 |
+
$url .= '?'.http_build_query($params);
|
124 |
+
}
|
125 |
+
|
126 |
+
$version = curl_version();
|
127 |
+
$baseUrl = self::API_URL;
|
128 |
+
if(!($version['features'] & CURL_VERSION_SSL)){ //Fallback to HTTP
|
129 |
+
$baseUrl = str_replace('https://', 'http://', $baseUrl);
|
130 |
+
}
|
131 |
+
|
132 |
+
$curl = curl_init($baseUrl.$url);
|
133 |
+
|
134 |
+
curl_setopt($curl, CURLOPT_USERPWD, $this->key);
|
135 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
|
136 |
+
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
137 |
+
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
138 |
+
curl_setopt($curl, CURLOPT_MAXREDIRS, 3);
|
139 |
+
|
140 |
+
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
|
141 |
+
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
|
142 |
+
|
143 |
+
curl_setopt($curl, CURLOPT_USERAGENT, self::USER_AGENT);
|
144 |
+
|
145 |
+
if($data !==null){
|
146 |
+
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
|
147 |
+
}
|
148 |
+
|
149 |
+
$this->lastResponseRaw = curl_exec($curl);
|
150 |
+
|
151 |
+
$errno = curl_errno($curl);
|
152 |
+
$error = curl_error($curl);
|
153 |
+
curl_close($curl);
|
154 |
+
|
155 |
+
if ($errno) throw new PrintfulException('CURL: '.$error, $errno);
|
156 |
+
|
157 |
+
$this->lastResponse = $response = json_decode($this->lastResponseRaw, true);
|
158 |
+
|
159 |
+
if(!isset($response['code'], $response['result'])){
|
160 |
+
throw new PrintfulException('Invalid API response');
|
161 |
+
}
|
162 |
+
$status = (int)$response['code'];
|
163 |
+
if($status < 200 || $status >= 300){
|
164 |
+
throw new PrintfulApiException((string)$response['result'], $status);
|
165 |
+
}
|
166 |
+
return $response['result'];
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Class PrintfulException Generic Printful exception
|
172 |
+
*/
|
173 |
+
class PrintfulException extends Exception {}
|
174 |
+
/**
|
175 |
+
* Class PrintfulException Printful exception returned from the API
|
176 |
+
*/
|
177 |
+
class PrintfulApiException extends PrintfulException {}
|
printful-shipping.php
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
Plugin Name: Printful Shipping Rates for WooCommerce
|
4 |
+
Plugin URI: https://wordpress.org/plugins/printful-shipping-for-woocommerce/
|
5 |
+
Description: Printful shipping rates
|
6 |
+
Version: 1.0
|
7 |
+
Author: Idea Bits LLC
|
8 |
+
License: GPL2 http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
+
*/
|
10 |
+
|
11 |
+
add_action('woocommerce_shipping_init', 'printful_shipping_init');
|
12 |
+
|
13 |
+
add_filter('woocommerce_shipping_methods', 'printful_shipping_add');
|
14 |
+
|
15 |
+
function printful_shipping_add($methods)
|
16 |
+
{
|
17 |
+
$methods [] = 'printful_shipping';
|
18 |
+
return $methods;
|
19 |
+
}
|
20 |
+
|
21 |
+
function printful_shipping_init()
|
22 |
+
{
|
23 |
+
|
24 |
+
if (!class_exists('WC_Shipping_Method') ) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
+
class Printful_Shipping extends WC_Shipping_Method
|
29 |
+
{
|
30 |
+
public $currencyRate = 1;
|
31 |
+
|
32 |
+
|
33 |
+
function __construct()
|
34 |
+
{
|
35 |
+
$this->id = 'printful_shipping';
|
36 |
+
$this->method_title = 'Printful Shipping';
|
37 |
+
$this->method_description = 'Calculate live shipping rates based on actual Printful shipping costs';
|
38 |
+
|
39 |
+
$this->init_form_fields();
|
40 |
+
$this->init_settings();
|
41 |
+
|
42 |
+
add_action('woocommerce_update_options_shipping_' . $this->id, array(&$this, 'process_admin_options'));
|
43 |
+
|
44 |
+
$this->enabled = $this->get_option('enabled');
|
45 |
+
$this->title = $this->get_option('title');
|
46 |
+
|
47 |
+
if (get_woocommerce_currency() != 'USD') {
|
48 |
+
$currencyRate = (float)$this->get_option('rate');
|
49 |
+
if($currencyRate>0) {
|
50 |
+
$this->currencyRate = $currencyRate;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
$this->type = 'order';
|
54 |
+
}
|
55 |
+
|
56 |
+
function init_form_fields()
|
57 |
+
{
|
58 |
+
$this->form_fields = array(
|
59 |
+
'enabled' => array(
|
60 |
+
'title' => __( 'Enable/Disable', 'woocommerce' ),
|
61 |
+
'type' => 'checkbox',
|
62 |
+
'label' => __( 'Enable this shipping method', 'woocommerce' ),
|
63 |
+
'default' => 'no'
|
64 |
+
),
|
65 |
+
'title' => array(
|
66 |
+
'title' => __( 'Method Title', 'woocommerce' ),
|
67 |
+
'type' => 'text',
|
68 |
+
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
|
69 |
+
'default' => __( 'Printful Shipping', 'woocommerce' ),
|
70 |
+
'desc_tip' => true,
|
71 |
+
),
|
72 |
+
'printful_key' => array(
|
73 |
+
'title' => 'Printful store API key',
|
74 |
+
'type' => 'text',
|
75 |
+
'desc_tip' => true,
|
76 |
+
'description'=> 'Your store\'s Printful API key. Create it in the Prinful dashboard',
|
77 |
+
'default' => '',
|
78 |
+
),
|
79 |
+
);
|
80 |
+
$currency = get_woocommerce_currency();
|
81 |
+
if ($currency != 'USD'){ //Require conversion rate
|
82 |
+
$this->form_fields['rate'] = array(
|
83 |
+
'title' => 'Currency conversion rate',
|
84 |
+
'type' => 'text',
|
85 |
+
'desc_tip' => true,
|
86 |
+
'description' => 'Currency rate used to convert Printful shipping prices from USD to ' . $currency .
|
87 |
+
'. For example if multiplier is 0.2, Printful price of 2 USD will be converted to 10 '.$currency,
|
88 |
+
'default' => '1',
|
89 |
+
);
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
function calculate_shipping($package = array())
|
94 |
+
{
|
95 |
+
if (!class_exists('PrintfulClient', false)) {
|
96 |
+
require dirname(__FILE__) . '/PrintfulClient.php';
|
97 |
+
}
|
98 |
+
|
99 |
+
$request = array(
|
100 |
+
'recipient' => array(
|
101 |
+
'address1' => $package['destination']['address'],
|
102 |
+
'address2' => $package['destination']['address_2'],
|
103 |
+
'city' => $package['destination']['city'],
|
104 |
+
'state_code' => $package['destination']['state'],
|
105 |
+
'country_code' => $package['destination']['country'],
|
106 |
+
'zip' => $package['destination']['postcode'],
|
107 |
+
),
|
108 |
+
'items' => array()
|
109 |
+
);
|
110 |
+
|
111 |
+
foreach ($package['contents'] as $item) {
|
112 |
+
$request['items'] []= array(
|
113 |
+
'external_variant_id' => $item['variation_id'] ? $item['variation_id'] : $item['product_id'],
|
114 |
+
'quantity' => $item['quantity']
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
try {
|
119 |
+
$printful = new PrintfulClient($this->get_option('printful_key'));
|
120 |
+
} catch( PrintfulException $e) {
|
121 |
+
wc_add_notice( $e->getMessage(), 'error' );
|
122 |
+
return false;
|
123 |
+
}
|
124 |
+
|
125 |
+
try {
|
126 |
+
$response = $printful->post('shipping/rates', $request, array(
|
127 |
+
'expedited' => true,
|
128 |
+
));
|
129 |
+
|
130 |
+
foreach ($response as $rate) {
|
131 |
+
$rateData = array(
|
132 |
+
'id' => $this->id . '_' . $rate['id'],
|
133 |
+
'label' => $rate['name'],
|
134 |
+
'cost' => round($rate['rate'] / $this->currencyRate, 2),
|
135 |
+
'taxes' => '',
|
136 |
+
'calc_tax' => 'per_order'
|
137 |
+
);
|
138 |
+
$this->add_rate($rateData);
|
139 |
+
}
|
140 |
+
} catch ( PrintfulException $e) {
|
141 |
+
if (WP_DEBUG) {
|
142 |
+
wc_add_notice( $e->getMessage(), 'error' );
|
143 |
+
}
|
144 |
+
return false;
|
145 |
+
}
|
146 |
+
}
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
|
151 |
+
|
152 |
+
|
readme.txt
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Printful live shipping rates for WooCommerce ===
|
2 |
+
Contributors: girts_u
|
3 |
+
Tags: woocommerce, printful, shipping, shipping rates, fulfillment, printing, fedex, carriers, checkout
|
4 |
+
Requires at least: 3.8
|
5 |
+
Tested up to: 4.0
|
6 |
+
Stable tag: 1.0
|
7 |
+
License: GPLv2 or later
|
8 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
+
|
10 |
+
Calculate live shipping rates based on actual Printful shipping costs
|
11 |
+
|
12 |
+
== Description ==
|
13 |
+
|
14 |
+
Display actual live shipping rates from carriers like FedEx on your WooCommerce checkout page. This plugin will return a list of available shipping rates specific to the shipping address your customer provides when checking out. These rates are identical to the list you get when you submit an order manually via Printful dashboard.
|
15 |
+
|
16 |
+
= Known Limitations =
|
17 |
+
|
18 |
+
* Works with WooCommmerce 2.1 and up
|
19 |
+
* Works only if every item in the order is fulfilled by Printful
|
20 |
+
|
21 |
+
== Installation ==
|
22 |
+
1. Upload 'printful-shipping' to the '/wp-content/plugins/' directory
|
23 |
+
1. Activate the plugin through the 'Plugins' menu in WordPress
|
24 |
+
1. Enable rate calculation by adding your Printful API key to WooCommerce->Settings->Shipping->Printful Shipping tab
|
25 |
+
|
26 |
+
== Frequently Asked Questions ==
|
27 |
+
|
28 |
+
= How do I get Printful API key? =
|
29 |
+
|
30 |
+
Go to https://www.theprintful.com/dashboard/store , select your WooCommerce store, click "Edit" and then click
|
31 |
+
"Enable API Access". Your API key will be generated and displayed there.
|
32 |
+
|
33 |
+
== Screenshots ==
|
34 |
+
|
35 |
+
1. Settings dialog
|
36 |
+
2. Shipping rate selection
|
37 |
+
|
38 |
+
== Upgrade Notice ==
|
39 |
+
|
40 |
+
= 1.0 =
|
41 |
+
* First release
|
42 |
+
|
43 |
+
== Changelog ==
|
44 |
+
|
45 |
+
= 1.0 =
|
46 |
+
* First release
|