Printful Integration for WooCommerce - Version 2.1

Version Description

Personalization feature

Download this release

Release Info

Developer printful
Plugin Icon 128x128 Printful Integration for WooCommerce
Version 2.1
Comparing to
See all releases

Code changes from version 2.0.8 to 2.1

assets/images/loading.gif ADDED
Binary file
assets/js/product-customizer.js ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** Define class */
2
+ var Printful_Product_Customizer;
3
+
4
+ (function () {
5
+ 'use strict';
6
+
7
+ /**
8
+ *
9
+ * @type {{modal: null, baseUrl: string, onCustomizeClick: onCustomizeClick, closeModal: closeModal, createModal: (function(string): HTMLDivElement), listenForResponse: listenForResponse, onCustomDesignSave: onCustomDesignSave}}
10
+ */
11
+ Printful_Product_Customizer = {
12
+ modal: null,
13
+ baseUrl: 'https://www.printful.com',
14
+
15
+ /**
16
+ * Handle click event
17
+ * @param {string} site_url
18
+ */
19
+ onCustomizeClick: function (site_url) {
20
+ var variation_id = jQuery('input[name="variation_id"]').val(); // get selected variation ID
21
+
22
+ if (!variation_id) {
23
+ return;
24
+ }
25
+
26
+ var url = this.baseUrl + '/product-customizer/?website=' + site_url + '&variant=' + variation_id;
27
+
28
+ document.body.appendChild(this.createModal(url));
29
+ //start listening to post messaged
30
+ this.listenForResponse();
31
+ },
32
+
33
+ /**
34
+ * Close the modal element
35
+ */
36
+ closeModal: function () {
37
+ if (this.modal) {
38
+ this.modal.parentNode.removeChild(this.modal);
39
+ this.modal = null;
40
+ }
41
+ },
42
+
43
+ /**
44
+ * Create modal content
45
+ * @param {string} url
46
+ * @returns {HTMLDivElement}
47
+ */
48
+ createModal: function (url) {
49
+ // clear the old one just to be sure
50
+ this.closeModal();
51
+
52
+ // create iframe
53
+ var isMobileSafari = false;
54
+ var userAgent = (window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : false;
55
+
56
+ if (userAgent && userAgent.match(/iPhone|iPad|iPod/i)) {
57
+ isMobileSafari = true;
58
+ }
59
+
60
+ var modal = document.createElement('div');
61
+ modal.className = 'pf-customize-modal';
62
+ modal.setAttribute('style', 'position: fixed; z-index: 2147483648; padding: 20px; top: 0; width: 100%; height: 100%; left: 0; background: rgba(0, 0 , 0, 0.6); box-sizing: border-box;');
63
+
64
+
65
+ var modalHeader = document.createElement('div');
66
+ modalHeader.setAttribute('style', 'padding: 15px; border-bottom: 1px solid #e5e5e5; overflow:hidden; position:absolute; top:0; left:0; width:100%; box-sizing: border-box;');
67
+
68
+ var closeBtn = document.createElement('button');
69
+ closeBtn.onclick = this.closeModal.bind(this);
70
+ closeBtn.setAttribute('style', 'height:30px; width:30px; cursor:pointer; border:0px; background:0 0; padding:0; -webkit-appearance:none; color:#000; float:right; background:none;');
71
+ var closeImg = document.createElement('img');
72
+ closeImg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAAAgVJREFUaAXtmU2KwkAQhZ0hQbyDu7mIB3PhwoN5EXfeIYguJo9JQRMydurnNYxTDTH+dNWr71VD2mSzyZEOpAPpQDqQDqQD6UA6kA6kA80dOJ1O++Px+NVKGFrQ9Oh9WoMhPAzD5fF4XFpAQwNa0PRAf1iABXaMle7e+r4/nM/nqyVfLUZgx3nS3etutzuMddxqsfPf1cALsJKTAr0AK3omaPWSfj6f21ERx3zso5f3C1hob6da5nW8/KzuMLJVCgnpNEvDBMyGZsGibjMwC5oJ6waOhmbDhgBHQbeADQP2QreCDQW2QreEDQfWQreGpQCvhcY8bFTGk2wX8ZWMkGu5JCvPrstSmWj+vta9aX5TWGjSgJG8Ao0p80HrrAhRgSGigKbDoh468EroJrCoRf1vCUF/edA7/K+WtAJWFg19adM6XIGVWzPvcVmqweL+F1r6FhuPNbBys08zV9a89xy6pC0AlhgPdBiwp3BPrBY+BDii4Igca+DdwJGFRub6Dd4FzCiQkbOENwMzC2PmNgEzC5JusDTUwKxCBLQ8M7TU/5a6rruPReGYj/B9MDYo065MtqKl5n2qpfyu+l7dYWRceIIYDltWvtBp05ND5DQBI7CA3jKfDUMLo4C+W58N/2RyvAIahThSqEKhBU1VUE5OB9KBdCAdSAfSgXQgHUgH0oEQB74BG1sUIwNoL3cAAAAASUVORK5CYII=';
73
+ closeImg.setAttribute('style', 'height:30px; width:30px;');
74
+ closeBtn.appendChild(closeImg);
75
+ modalHeader.appendChild(closeBtn);
76
+
77
+ var modalHeaderTitle = document.createElement('h4');
78
+ modalHeaderTitle.className = 'product-customizer__header-title';
79
+ modalHeaderTitle.setAttribute('style', 'float: left;font-weight:bold;font-size:23px;color:#222;line-height:30px;margin:0px;clear:none;');
80
+ modalHeaderTitle.innerText = 'Create a personalized design';
81
+ modalHeader.appendChild(modalHeaderTitle);
82
+
83
+ var modalContent = document.createElement('div');
84
+ modalContent.setAttribute('style', 'background-color: #fff; width: 100%; height: 100%;overflow:hidden;position:relative');
85
+ modalContent.appendChild(modalHeader);
86
+
87
+ var styles = document.createElement('style');
88
+ styles.innerHTML = '@media screen and (max-width: 768px) { .product-customizer__header-title {font-size: 16px !important;} }';
89
+ modalContent.appendChild(styles);
90
+
91
+ modal.appendChild(modalContent);
92
+
93
+ var iframe = document.createElement('iframe');
94
+ iframe.src = url;
95
+ iframe.width = '100%';
96
+ iframe.height = '100%';
97
+
98
+ if (isMobileSafari) {
99
+ var iframeWrapper = document.createElement('div');
100
+ iframeWrapper.setAttribute('style', '-webkit-overflow-scrolling: touch; overflow: scroll; height: 100%; top: 61px; box-sizing: border-box; position: absolute; width: 100%; padding-bottom: 60px;');
101
+ iframe.setAttribute('style', 'border: 0; box-sizing: border-box;');
102
+ iframeWrapper.appendChild(iframe);
103
+ modalContent.appendChild(iframeWrapper);
104
+ } else {
105
+ iframe.setAttribute('style', 'border: 0; padding-top: 60px; box-sizing: border-box;');
106
+ modalContent.appendChild(iframe);
107
+ }
108
+
109
+
110
+ this.modal = modal;
111
+
112
+ return modal;
113
+ },
114
+
115
+ /**
116
+ * Listen for response from PF
117
+ */
118
+ listenForResponse: function () {
119
+ var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
120
+ var eventer = window[eventMethod];
121
+ var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
122
+ eventer(messageEvent, function (e) {
123
+ if (e.origin !== this.baseUrl) {
124
+ return;
125
+ }
126
+
127
+ if (typeof e.data['action'] === 'undefined' || e.data['action'] !== 'PFProductCustomized') {
128
+ return;
129
+ }
130
+
131
+ this.onCustomDesignSave(e.data['hash']);
132
+ }.bind(this));
133
+ },
134
+
135
+ /**
136
+ * Manage response from PF
137
+ * @param {string} hash
138
+ */
139
+ onCustomDesignSave: function (hash) {
140
+ jQuery('#pfc_hash').val(hash);
141
+ this.closeModal();
142
+
143
+ jQuery('.variations_form').submit();
144
+ }
145
+ };
146
+ })();
147
+
148
+ setInterval(function () {
149
+ /**
150
+ * @type {Array<HTMLImageElement>}
151
+ */
152
+ var toCheck = [];
153
+
154
+ jQuery('img.pf-image-pending').each(function () {
155
+ jQuery(this).removeClass('pf-image-pending');
156
+ jQuery(this).addClass('pf-image-checking');
157
+ toCheck.push(this);
158
+ });
159
+
160
+ var hashes = toCheck.reduce(function(carry, image){
161
+ carry[image.getAttribute('data-hash')] = image;
162
+
163
+ return carry;
164
+ }, {});
165
+
166
+ // if pending (loading) images exist, request image urls
167
+ if (Object.keys(hashes).length > 0) {
168
+ jQuery.ajax({
169
+ url: '/wp-admin/admin-ajax.php',
170
+ type: 'GET',
171
+ data: {
172
+ action: 'printful_customized_thumb',
173
+ hashes: Object.keys(hashes)
174
+ },
175
+ success: function (response) {
176
+ var result = JSON.parse(response);
177
+ for (var hash in result){
178
+ var image = hashes[hash];
179
+
180
+ if (result[hash]) {
181
+ image.src = result[hash];
182
+ jQuery(image).removeClass('pf-image-checking');
183
+ } else {
184
+ jQuery(image).removeClass('pf-image-checking');
185
+ jQuery(image).addClass('pf-image-pending');
186
+ }
187
+ }
188
+ }
189
+ });
190
+ }
191
+ }, 2000);
includes/class-printful-admin-settings.php CHANGED
@@ -10,6 +10,8 @@ class Printful_Admin_Settings {
10
  const CARRIER_TYPE_INTERNATIONAL = 'international';
11
  const CARRIER_REGION_US = 'US';
12
  const CARRIER_REGION_EU = 'LV';
 
 
13
 
14
  /**
15
  * @return array
@@ -45,6 +47,18 @@ class Printful_Admin_Settings {
45
  'label' => __( 'Use HTTP instead of HTTPS to connect to the Printful API (may be required if the plugin does not work for some hosting configurations)', 'printful' ),
46
  'default' => 'no',
47
  ),
 
 
 
 
 
 
 
 
 
 
 
 
48
  );
49
  }
50
 
10
  const CARRIER_TYPE_INTERNATIONAL = 'international';
11
  const CARRIER_REGION_US = 'US';
12
  const CARRIER_REGION_EU = 'LV';
13
+ const DEFAULT_PERSONALIZE_BUTTON_TEXT = 'Personalize Design';
14
+ const DEFAULT_PERSONALIZE_BUTTON_COLOR = '#eee';
15
 
16
  /**
17
  * @return array
47
  'label' => __( 'Use HTTP instead of HTTPS to connect to the Printful API (may be required if the plugin does not work for some hosting configurations)', 'printful' ),
48
  'default' => 'no',
49
  ),
50
+ 'pfc_button_text' => array(
51
+ 'title' => __( 'Personalization button text', 'printful' ),
52
+ 'type' => 'text',
53
+ 'description' => __( 'Personalization button text', 'printful' ),
54
+ 'default' => self::DEFAULT_PERSONALIZE_BUTTON_TEXT
55
+ ),
56
+ 'pfc_button_color' => array(
57
+ 'title' => __( 'Personalization button color', 'printful' ),
58
+ 'type' => 'color-picker',
59
+ 'description' => __( 'Personalization button background color', 'printful' ),
60
+ 'default' => self::DEFAULT_PERSONALIZE_BUTTON_COLOR,
61
+ )
62
  );
63
  }
64
 
includes/class-printful-admin.php CHANGED
@@ -35,6 +35,7 @@ class Printful_Admin {
35
  wp_enqueue_style( 'printful-global', plugins_url( '../assets/css/global.css', __FILE__ ) );
36
 
37
  if ( strpos( $hook, 'printful-dashboard' ) !== false ) {
 
38
  wp_enqueue_style( 'printful-dashboard', plugins_url( '../assets/css/dashboard.css', __FILE__ ) );
39
  wp_enqueue_style( 'printful-status', plugins_url( '../assets/css/status.css', __FILE__ ) );
40
  wp_enqueue_style( 'printful-support', plugins_url( '../assets/css/support.css', __FILE__ ) );
@@ -57,6 +58,7 @@ class Printful_Admin {
57
  */
58
  public function add_admin_scripts($hook) {
59
  if ( strpos( $hook, 'printful-dashboard' ) !== false ) {
 
60
  wp_enqueue_script( 'printful-settings', plugins_url( '../assets/js/settings.js', __FILE__ ) );
61
  wp_enqueue_script( 'printful-connect', plugins_url( '../assets/js/connect.js', __FILE__ ) );
62
  wp_enqueue_script( 'printful-block-loader', plugins_url( '../assets/js/block-loader.js', __FILE__ ) );
35
  wp_enqueue_style( 'printful-global', plugins_url( '../assets/css/global.css', __FILE__ ) );
36
 
37
  if ( strpos( $hook, 'printful-dashboard' ) !== false ) {
38
+ wp_enqueue_style( 'wp-color-picker' );
39
  wp_enqueue_style( 'printful-dashboard', plugins_url( '../assets/css/dashboard.css', __FILE__ ) );
40
  wp_enqueue_style( 'printful-status', plugins_url( '../assets/css/status.css', __FILE__ ) );
41
  wp_enqueue_style( 'printful-support', plugins_url( '../assets/css/support.css', __FILE__ ) );
58
  */
59
  public function add_admin_scripts($hook) {
60
  if ( strpos( $hook, 'printful-dashboard' ) !== false ) {
61
+ wp_enqueue_script( 'wp-color-picker' );
62
  wp_enqueue_script( 'printful-settings', plugins_url( '../assets/js/settings.js', __FILE__ ) );
63
  wp_enqueue_script( 'printful-connect', plugins_url( '../assets/js/connect.js', __FILE__ ) );
64
  wp_enqueue_script( 'printful-block-loader', plugins_url( '../assets/js/block-loader.js', __FILE__ ) );
includes/class-printful-api-resource.php CHANGED
@@ -97,7 +97,6 @@ class Printful_API_Resource extends WC_API_Resource {
97
 
98
  return array(
99
  'version' => Printful_Base::VERSION,
100
- 'api_key' => Printful_Integration::instance()->get_option('printful_key'),
101
  'store_id' => ! empty( $storeData['id'] ) ? $storeData['id'] : false,
102
  'error' => $error,
103
  'status_checklist' => $checklist,
97
 
98
  return array(
99
  'version' => Printful_Base::VERSION,
 
100
  'store_id' => ! empty( $storeData['id'] ) ? $storeData['id'] : false,
101
  'error' => $error,
102
  'status_checklist' => $checklist,
includes/class-printful-customizer.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit;
3
+
4
+ class Printful_Customizer {
5
+
6
+ /**
7
+ * Initialize the values, hooks and actions
8
+ */
9
+ public static function init()
10
+ {
11
+ $customizer = new self;
12
+
13
+ $customizer->hook_actions();
14
+ }
15
+
16
+ public function hook_actions()
17
+ {
18
+ // Save customized product as independent cart item data
19
+ add_filter( 'woocommerce_add_cart_item_data', array( $this, 'save_customizer_hash_data_to_cart' ), 10, 1 );
20
+ add_filter( 'woocommerce_cart_item_thumbnail', array( $this, 'change_woocommerce_cart_item_thumbnail' ), 20, 2 );
21
+ // add property to order
22
+ add_action('woocommerce_add_order_item_meta', array( $this, 'save_customizer_hash_order_meta' ), 10, 3 );
23
+
24
+ add_action( 'wp_ajax_printful_customized_thumb', array( $this, 'printful_customized_thumb' ) );
25
+ add_action( 'wp_ajax_nopriv_printful_customized_thumb', array( $this, 'printful_customized_thumb' ) );
26
+ }
27
+
28
+ /**
29
+ * @param $cart_item_data
30
+ * @return mixed
31
+ */
32
+ public function save_customizer_hash_data_to_cart( $cart_item_data ) {
33
+ if ( isset( $_POST['pfc_hash'] ) && ! empty( $_POST['pfc_hash'] ) ) {
34
+ // Set the custom data in the cart item
35
+ $cart_item_data['pfc_hash'] = (string) sanitize_text_field( $_POST['pfc_hash'] );
36
+ // set pending actual image property, so it is not reloaded each time
37
+ $cart_item_data['customizer_image_generated'] = false;
38
+
39
+ // Make each item as a unique separated cart item
40
+ $cart_item_data['unique_key'] = md5( microtime().rand() );
41
+ }
42
+
43
+ return $cart_item_data;
44
+ }
45
+
46
+ public function change_woocommerce_cart_item_thumbnail( $thumbnail, $cart_item )
47
+ {
48
+ if ( $cart_item
49
+ && !empty( $cart_item['pfc_hash'] )
50
+ && empty( $cart_item['customizer_image_generated'] )
51
+ ) {
52
+ $class = 'attachment-shop_thumbnail wp-post-image'; // Default cart thumbnail class.
53
+ $src = esc_url( Printful_Base::get_asset_url() . 'images/loading.gif' );
54
+ // Construct img tag.
55
+ return "<img src='{$src}' class='{$class} pf-image-pending' data-hash='{$cart_item['pfc_hash']}' />";
56
+ } else if ($cart_item
57
+ && !empty( $cart_item['pfc_hash'] )
58
+ && !empty( $cart_item['customizer_image_generated'] )
59
+ && empty( $cart_item['customizer_image_loaded'] )
60
+ && !empty( $cart_item['customizer_image'] )
61
+ ) {
62
+ $class = 'attachment-shop_thumbnail wp-post-image'; // Default cart thumbnail class.
63
+ // Construct img tag.
64
+ return "<img src='{$cart_item['customizer_image']}' class='{$class}' data-hash='{$cart_item['pfc_hash']}' />";
65
+ }
66
+
67
+ return $thumbnail;
68
+ }
69
+
70
+ /**
71
+ * @param $itemId
72
+ * @param $values
73
+ * @param $key
74
+ *
75
+ * @throws Exception
76
+ */
77
+ public function save_customizer_hash_order_meta( $itemId, $values, $key )
78
+ {
79
+ if ( isset( $values['pfc_hash'] ) ) {
80
+ wc_add_order_item_meta( $itemId, 'pfc_hash', $values['pfc_hash'] );
81
+ }
82
+ }
83
+
84
+ /**
85
+ * @throws PrintfulException
86
+ * @throws Exception
87
+ */
88
+ public static function printful_customized_thumb()
89
+ {
90
+ if ( empty( $_GET['hashes'] ) ) {
91
+ return;
92
+ }
93
+
94
+ $client = Printful_Integration::instance()->get_client();
95
+ $hashes = implode(',', $_GET['hashes']);
96
+ $response = $client->get('woocommerce/get-hash-images', array(
97
+ 'hashes' => $hashes
98
+ ));
99
+
100
+ // global $woocommerce;
101
+ $items = WC()->cart->get_cart();
102
+
103
+ foreach ($items as $key => $item) {
104
+ if ( isset( $item['pfc_hash'] ) ) {
105
+ foreach ($response as $hash => $image_url) {
106
+ if ($hash !== $item['pfc_hash']) {
107
+ continue;
108
+ }
109
+
110
+ WC()->cart->cart_contents[$key]['customizer_image_generated'] = true;
111
+ WC()->cart->cart_contents[$key]['customizer_image'] = $image_url;
112
+ WC()->cart->cart_contents[$key]['customizer_image_loaded'] = false;
113
+ }
114
+ }
115
+ }
116
+
117
+ WC()->cart->set_session();
118
+
119
+ echo json_encode($response);
120
+ exit;
121
+ }
122
+ }
includes/class-printful-rest-api-controller.php CHANGED
@@ -176,7 +176,6 @@ class Printful_REST_API_Controller extends WC_REST_Controller
176
 
177
  return array(
178
  'version' => Printful_Base::VERSION,
179
- 'api_key' => Printful_Integration::instance()->get_option('printful_key'),
180
  'store_id' => ! empty( $store_data['id'] ) ? $store_data['id'] : false,
181
  'error' => $error,
182
  'status_checklist' => $checklist,
176
 
177
  return array(
178
  'version' => Printful_Base::VERSION,
 
179
  'store_id' => ! empty( $store_data['id'] ) ? $store_data['id'] : false,
180
  'error' => $error,
181
  'status_checklist' => $checklist,
includes/class-printful-template.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit;
3
+
4
+ class Printful_Template {
5
+
6
+ /**
7
+ * Initialize the values, hooks and actions
8
+ */
9
+ public static function init()
10
+ {
11
+ $template = new self;
12
+
13
+ $template->hook_templates();
14
+ }
15
+
16
+ /**
17
+ * Hook custom modifications in template files
18
+ */
19
+ public function hook_templates()
20
+ {
21
+ // hook templates, 29 indicates position, right before variation selection
22
+ add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'printful_template_customize_button' ), 20 );
23
+ // add a hidden input field
24
+ add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'printful_customizer_hash_field' ), 11 );
25
+ }
26
+
27
+ /**
28
+ * Hook callback for personalization button within product page
29
+ */
30
+ public static function printful_template_customize_button()
31
+ {
32
+ global $post;
33
+
34
+ if ( $post && get_post_meta( $post->ID, 'pf_customizable', true ) ) {
35
+ // bind script that's responsible for manipulation with personalization
36
+ wp_enqueue_script( 'printful-product-customizer', plugins_url( '../assets/js/product-customizer.js', __FILE__ ) );
37
+ // load template for personalization button
38
+ Printful_Admin::load_template( 'personalize-button', array(
39
+ 'site_url' => get_site_url(),
40
+ 'pfc_button_color' => Printful_Integration::instance()->get_option( 'pfc_button_color' ) ?: Printful_Admin_Settings::DEFAULT_PERSONALIZE_BUTTON_COLOR,
41
+ 'pfc_button_text' => Printful_Integration::instance()->get_option( 'pfc_button_text' ) ?: Printful_Admin_Settings::DEFAULT_PERSONALIZE_BUTTON_TEXT
42
+ ) );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Add hidden customizer hash ID field to form
48
+ */
49
+ public static function printful_customizer_hash_field()
50
+ {
51
+ Printful_Admin::load_template( 'customizer-hidden-input' );
52
+ }
53
+ }
includes/templates/customizer-hidden-input.php ADDED
@@ -0,0 +1 @@
 
1
+ <input type="hidden" id="pfc_hash" name="pfc_hash" value="">
includes/templates/personalize-button.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var string $site_url
4
+ * @var string $pfc_button_text
5
+ */
6
+ ?>
7
+ <a class="button"
8
+ style="background-color: <?php esc_attr_e($pfc_button_color); ?>"
9
+ onclick="Printful_Product_Customizer.onCustomizeClick( '<?php echo esc_url($site_url); ?>')">
10
+ <?php esc_html_e($pfc_button_text, 'printful'); ?>
11
+ </a>
includes/templates/setting-group.php CHANGED
@@ -69,6 +69,9 @@
69
 
70
  <?php endforeach; ?>
71
 
 
 
 
72
  <?php endif; ?>
73
 
74
  </fieldset>
@@ -81,4 +84,9 @@
81
 
82
  <?php endif; ?>
83
 
84
- </div>
 
 
 
 
 
69
 
70
  <?php endforeach; ?>
71
 
72
+ <?php elseif ($setting['type'] == 'color-picker') : ?>
73
+ <label for="<?php esc_attr_e($key); ?>">
74
+ <input type="text" name="<?php esc_attr_e($key); ?>" class="<?php esc_attr_e($key); ?>" value="<?php esc_attr_e($setting['value']); ?>" data-default-color="<?php esc_attr_e($setting['default']); ?>" />
75
  <?php endif; ?>
76
 
77
  </fieldset>
84
 
85
  <?php endif; ?>
86
 
87
+ </div>
88
+ <script>
89
+ jQuery(document).ready(function($){
90
+ $('.pfc_button_color').wpColorPicker();
91
+ });
92
+ </script>
printful-shipping.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Printful Integration for WooCommerce
4
  Plugin URI: https://wordpress.org/plugins/printful-shipping-for-woocommerce/
5
  Description: Calculate correct shipping and tax rates for your Printful-Woocommerce integration.
6
- Version: 2.0.8
7
  Author: Printful
8
  Author URI: http://www.printful.com
9
  License: GPL2 http://www.gnu.org/licenses/gpl-2.0.html
@@ -20,7 +20,7 @@ if ( ! defined( 'PF_PLUGIN_FILE' ) ) {
20
 
21
  class Printful_Base {
22
 
23
- const VERSION = '2.0.8';
24
  const PF_HOST = 'https://www.printful.com/';
25
  const PF_API_HOST = 'https://api.printful.com/';
26
 
@@ -64,6 +64,8 @@ class Printful_Base {
64
  require_once 'includes/class-printful-size-chart-tab.php';
65
  require_once 'includes/class-printful-size-chart-tab.php';
66
  require_once 'includes/class-printful-rest-api-controller.php';
 
 
67
 
68
  //launch init
69
  Printful_Taxes::init();
@@ -71,6 +73,8 @@ class Printful_Base {
71
  Printful_Request_log::init();
72
  Printful_Admin::init();
73
  Printful_Size_Chart_Tab::init();
 
 
74
 
75
  //hook ajax callbacks
76
  add_action( 'wp_ajax_save_printful_settings', array( 'Printful_Admin_Settings', 'save_printful_settings' ) );
@@ -111,6 +115,7 @@ class Printful_Base {
111
  public static function add_extra_info_to_api_index($available) {
112
  $available['printful_plugin_version'] = self::VERSION;
113
  $available['locale'] = get_locale();
 
114
  return $available;
115
  }
116
 
3
  Plugin Name: Printful Integration for WooCommerce
4
  Plugin URI: https://wordpress.org/plugins/printful-shipping-for-woocommerce/
5
  Description: Calculate correct shipping and tax rates for your Printful-Woocommerce integration.
6
+ Version: 2.1
7
  Author: Printful
8
  Author URI: http://www.printful.com
9
  License: GPL2 http://www.gnu.org/licenses/gpl-2.0.html
20
 
21
  class Printful_Base {
22
 
23
+ const VERSION = '2.1';
24
  const PF_HOST = 'https://www.printful.com/';
25
  const PF_API_HOST = 'https://api.printful.com/';
26
 
64
  require_once 'includes/class-printful-size-chart-tab.php';
65
  require_once 'includes/class-printful-size-chart-tab.php';
66
  require_once 'includes/class-printful-rest-api-controller.php';
67
+ require_once 'includes/class-printful-template.php';
68
+ require_once 'includes/class-printful-customizer.php';
69
 
70
  //launch init
71
  Printful_Taxes::init();
73
  Printful_Request_log::init();
74
  Printful_Admin::init();
75
  Printful_Size_Chart_Tab::init();
76
+ Printful_Template::init();
77
+ Printful_Customizer::init();
78
 
79
  //hook ajax callbacks
80
  add_action( 'wp_ajax_save_printful_settings', array( 'Printful_Admin_Settings', 'save_printful_settings' ) );
115
  public static function add_extra_info_to_api_index($available) {
116
  $available['printful_plugin_version'] = self::VERSION;
117
  $available['locale'] = get_locale();
118
+
119
  return $available;
120
  }
121
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: girts_u, kievins, kberzins
3
  Tags: woocommerce, printful, drop shipping, shipping, shipping rates, fulfillment, printing, fedex, carriers, checkout, t-shirts
4
  Requires at least: 3.8
5
  Tested up to: 5.1
6
- Stable tag: 2.0.8
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -38,6 +38,9 @@ Go to https://www.printful.com/dashboard/store , select your WooCommerce store,
38
 
39
  == Upgrade Notice ==
40
 
 
 
 
41
  = 2.0.8 =
42
  Shipping & Tax information improvements
43
 
@@ -112,6 +115,9 @@ First release
112
 
113
  == Changelog ==
114
 
 
 
 
115
  = 2.0.8 =
116
  * Shipping & Tax information improvements
117
 
3
  Tags: woocommerce, printful, drop shipping, shipping, shipping rates, fulfillment, printing, fedex, carriers, checkout, t-shirts
4
  Requires at least: 3.8
5
  Tested up to: 5.1
6
+ Stable tag: 2.1
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
38
 
39
  == Upgrade Notice ==
40
 
41
+ = 2.1 =
42
+ Personalization feature
43
+
44
  = 2.0.8 =
45
  Shipping & Tax information improvements
46
 
115
 
116
  == Changelog ==
117
 
118
+ = 2.1 =
119
+ * Personalization feature
120
+
121
  = 2.0.8 =
122
  * Shipping & Tax information improvements
123