Version Description
Advanced size guide feature
Download this release
Release Info
Developer | printful |
Plugin | Printful Integration for WooCommerce |
Version | 2.1.14 |
Comparing to | |
See all releases |
Code changes from version 2.1.13 to 2.1.14
- assets/css/dashboard.css +180 -180
- assets/css/global.css +18 -18
- assets/css/settings.css +45 -45
- assets/css/size-guide.css +171 -0
- assets/css/status.css +20 -20
- assets/css/support.css +61 -61
- assets/images/connect.svg +74 -74
- assets/js/block-loader.js +21 -21
- assets/js/connect.js +59 -59
- assets/js/intercom.min.js +11 -11
- assets/js/product-size-guide.js +439 -0
- assets/js/settings.js +43 -43
- i18n/languages/printful.pot +113 -28
- includes/class-printful-admin-settings.php +129 -32
- includes/class-printful-admin.php +171 -171
- includes/class-printful-client.php +191 -191
- includes/class-printful-integration.php +164 -164
- includes/class-printful-request-log.php +150 -150
- includes/class-printful-rest-api-controller.php +30 -1
- includes/class-printful-size-chart-tab.php +128 -123
- includes/class-printful-size-guide.php +211 -0
- includes/class-printful-taxes.php +188 -188
- includes/class-printful-template.php +26 -1
- includes/templates/ajax-loader.php +10 -10
- includes/templates/connect.php +39 -39
- includes/templates/header.php +19 -19
- includes/templates/inline-script.php +2 -2
- includes/templates/order-table.php +68 -68
- includes/templates/personalize-button.php +11 -11
- includes/templates/setting-group.php +13 -2
- includes/templates/setting-submit.php +23 -23
- includes/templates/shipping-notification.php +3 -3
- includes/templates/size-guide-button.php +10 -0
- includes/templates/stats.php +43 -43
- includes/templates/status-report.php +22 -22
- includes/templates/support-info.php +26 -26
- printful-shipping.php +5 -3
- readme.txt +8 -2
assets/css/dashboard.css
CHANGED
@@ -1,181 +1,181 @@
|
|
1 |
-
.printful-connect {
|
2 |
-
position: relative;
|
3 |
-
height: 100%;
|
4 |
-
}
|
5 |
-
|
6 |
-
.printful-connect-inner {
|
7 |
-
max-width: 600px;
|
8 |
-
margin: 100px auto 0 auto;
|
9 |
-
text-align: center;
|
10 |
-
position: relative;
|
11 |
-
}
|
12 |
-
.printful-connect .connect-image {
|
13 |
-
max-width: 100%;
|
14 |
-
}
|
15 |
-
.printful-connect h1 {
|
16 |
-
margin-bottom: 30px;
|
17 |
-
font-size: 34px;
|
18 |
-
}
|
19 |
-
.printful-connect .connect-description {
|
20 |
-
margin: 20px 0 30px 0;
|
21 |
-
}
|
22 |
-
|
23 |
-
/*noinspection CssUnusedSymbol*/
|
24 |
-
.printful-connect .printful-connect-button {
|
25 |
-
height: 53px;
|
26 |
-
line-height: 53px;
|
27 |
-
padding: 0 40px;
|
28 |
-
font-size: 18px;
|
29 |
-
}
|
30 |
-
|
31 |
-
.printful-stats {
|
32 |
-
position: relative;
|
33 |
-
margin: 20px 0 50px 0;
|
34 |
-
background-color: #fff;
|
35 |
-
padding: 30px 20px;
|
36 |
-
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
37 |
-
border-left: #0073aa 4px solid;
|
38 |
-
}
|
39 |
-
.printful-stats .printful-stats-item {
|
40 |
-
width: 49%;
|
41 |
-
display: inline-block;
|
42 |
-
margin-bottom: 25px;
|
43 |
-
box-sizing: border-box;
|
44 |
-
vertical-align: top;
|
45 |
-
padding: 0 8px;
|
46 |
-
}
|
47 |
-
|
48 |
-
.printful-stats .printful-stats-item h4 {
|
49 |
-
margin: 0 0 10px 0;
|
50 |
-
font-size: 24px;
|
51 |
-
line-height: 26px;
|
52 |
-
}
|
53 |
-
.printful-stats .printful-stats-item h4 .dashicons {
|
54 |
-
font-size: 26px;
|
55 |
-
width: 26px;
|
56 |
-
height: 26px;
|
57 |
-
}
|
58 |
-
|
59 |
-
/*noinspection ALL*/
|
60 |
-
.printful-stats .printful-stats-item h4 .dashicons-arrow-up-alt {
|
61 |
-
color: green;
|
62 |
-
}
|
63 |
-
.printful-stats .printful-stats-item h4 .dashicons-arrow-down-alt {
|
64 |
-
color: #d54e21;
|
65 |
-
}
|
66 |
-
|
67 |
-
@media (min-width: 768px) {
|
68 |
-
.printful-stats .printful-stats-item {
|
69 |
-
width: 24%;
|
70 |
-
margin-bottom: 0;
|
71 |
-
padding: 0 25px;
|
72 |
-
}
|
73 |
-
.printful-stats .printful-stats-item h4 {
|
74 |
-
font-size: 32px;
|
75 |
-
line-height: 36px;
|
76 |
-
}
|
77 |
-
.printful-stats .printful-stats-item h4 .dashicons {
|
78 |
-
padding-top: 4px;
|
79 |
-
font-size: 30px;
|
80 |
-
width: 30px;
|
81 |
-
height: 30px;
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
.printful-latest-orders {
|
86 |
-
display: table;
|
87 |
-
width: 100%;
|
88 |
-
margin-bottom: 50px;
|
89 |
-
}
|
90 |
-
.printful-latest-orders .row {
|
91 |
-
display: table-row;
|
92 |
-
}
|
93 |
-
.printful-latest-orders .row .cell {
|
94 |
-
display: table-cell;
|
95 |
-
}
|
96 |
-
|
97 |
-
.wrap h2.nav-tab-wrapper.printful-tabs {
|
98 |
-
margin-bottom: 15px;
|
99 |
-
}
|
100 |
-
|
101 |
-
|
102 |
-
.printful-quick-links {
|
103 |
-
position: relative;
|
104 |
-
margin-bottom: 30px;
|
105 |
-
}
|
106 |
-
.printful-quick-links .printful-quick-links-item {
|
107 |
-
width: 120px;
|
108 |
-
background: #fff;
|
109 |
-
border: solid 1px #e1e1e1;
|
110 |
-
float: left;
|
111 |
-
padding: 20px;
|
112 |
-
margin-right: 25px;
|
113 |
-
margin-bottom: 25px;
|
114 |
-
text-align: center;
|
115 |
-
text-decoration: none;
|
116 |
-
}
|
117 |
-
.printful-quick-links .printful-quick-links-item .dashicons {
|
118 |
-
font-size: 40px;
|
119 |
-
width: 40px;
|
120 |
-
height: 40px;
|
121 |
-
text-decoration: none;
|
122 |
-
color: #444;
|
123 |
-
}
|
124 |
-
.printful-quick-links .printful-quick-links-item h4 {
|
125 |
-
text-decoration: none;
|
126 |
-
color: #444;
|
127 |
-
margin: 5px 0 0 0;
|
128 |
-
}
|
129 |
-
.printful-quick-links .printful-quick-links-item:hover {
|
130 |
-
cursor: pointer;
|
131 |
-
}
|
132 |
-
.printful-quick-links .printful-quick-links-item:hover .dashicons,
|
133 |
-
.printful-quick-links .printful-quick-links-item:hover h4 {
|
134 |
-
color: #0D72B2;
|
135 |
-
}
|
136 |
-
|
137 |
-
.printful-error {
|
138 |
-
margin-top: 20px;
|
139 |
-
}
|
140 |
-
|
141 |
-
.printful-notice {
|
142 |
-
background: #fff;
|
143 |
-
border-left: 4px solid #dc3232;
|
144 |
-
padding: 1px 12px;
|
145 |
-
margin: 10px 0 20px 0;
|
146 |
-
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
147 |
-
text-align: left;
|
148 |
-
}
|
149 |
-
.printful-notice li {
|
150 |
-
font-weight: bold;
|
151 |
-
margin-left: 20px;
|
152 |
-
list-style: disc;
|
153 |
-
}
|
154 |
-
|
155 |
-
.block-loader {
|
156 |
-
text-align: center;
|
157 |
-
padding: 20px 0;
|
158 |
-
line-height: 20px;
|
159 |
-
}
|
160 |
-
.block-loader .message {
|
161 |
-
padding-left: 10px;
|
162 |
-
line-height: 20px;
|
163 |
-
display: inline-block;
|
164 |
-
font-size: 16px;
|
165 |
-
}
|
166 |
-
.block-loader .loader {
|
167 |
-
vertical-align: top;
|
168 |
-
}
|
169 |
-
|
170 |
-
#wpfooter::after {
|
171 |
-
box-sizing: border-box;
|
172 |
-
content: "";
|
173 |
-
width: 64px;
|
174 |
-
left: 50%;
|
175 |
-
margin-left: -32px;
|
176 |
-
height: 28px;
|
177 |
-
position: absolute;
|
178 |
-
bottom: 0;
|
179 |
-
background: url("../images/printful-logo-footer.png") no-repeat bottom center;
|
180 |
-
background-size: 64px;
|
181 |
}
|
1 |
+
.printful-connect {
|
2 |
+
position: relative;
|
3 |
+
height: 100%;
|
4 |
+
}
|
5 |
+
|
6 |
+
.printful-connect-inner {
|
7 |
+
max-width: 600px;
|
8 |
+
margin: 100px auto 0 auto;
|
9 |
+
text-align: center;
|
10 |
+
position: relative;
|
11 |
+
}
|
12 |
+
.printful-connect .connect-image {
|
13 |
+
max-width: 100%;
|
14 |
+
}
|
15 |
+
.printful-connect h1 {
|
16 |
+
margin-bottom: 30px;
|
17 |
+
font-size: 34px;
|
18 |
+
}
|
19 |
+
.printful-connect .connect-description {
|
20 |
+
margin: 20px 0 30px 0;
|
21 |
+
}
|
22 |
+
|
23 |
+
/*noinspection CssUnusedSymbol*/
|
24 |
+
.printful-connect .printful-connect-button {
|
25 |
+
height: 53px;
|
26 |
+
line-height: 53px;
|
27 |
+
padding: 0 40px;
|
28 |
+
font-size: 18px;
|
29 |
+
}
|
30 |
+
|
31 |
+
.printful-stats {
|
32 |
+
position: relative;
|
33 |
+
margin: 20px 0 50px 0;
|
34 |
+
background-color: #fff;
|
35 |
+
padding: 30px 20px;
|
36 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
37 |
+
border-left: #0073aa 4px solid;
|
38 |
+
}
|
39 |
+
.printful-stats .printful-stats-item {
|
40 |
+
width: 49%;
|
41 |
+
display: inline-block;
|
42 |
+
margin-bottom: 25px;
|
43 |
+
box-sizing: border-box;
|
44 |
+
vertical-align: top;
|
45 |
+
padding: 0 8px;
|
46 |
+
}
|
47 |
+
|
48 |
+
.printful-stats .printful-stats-item h4 {
|
49 |
+
margin: 0 0 10px 0;
|
50 |
+
font-size: 24px;
|
51 |
+
line-height: 26px;
|
52 |
+
}
|
53 |
+
.printful-stats .printful-stats-item h4 .dashicons {
|
54 |
+
font-size: 26px;
|
55 |
+
width: 26px;
|
56 |
+
height: 26px;
|
57 |
+
}
|
58 |
+
|
59 |
+
/*noinspection ALL*/
|
60 |
+
.printful-stats .printful-stats-item h4 .dashicons-arrow-up-alt {
|
61 |
+
color: green;
|
62 |
+
}
|
63 |
+
.printful-stats .printful-stats-item h4 .dashicons-arrow-down-alt {
|
64 |
+
color: #d54e21;
|
65 |
+
}
|
66 |
+
|
67 |
+
@media (min-width: 768px) {
|
68 |
+
.printful-stats .printful-stats-item {
|
69 |
+
width: 24%;
|
70 |
+
margin-bottom: 0;
|
71 |
+
padding: 0 25px;
|
72 |
+
}
|
73 |
+
.printful-stats .printful-stats-item h4 {
|
74 |
+
font-size: 32px;
|
75 |
+
line-height: 36px;
|
76 |
+
}
|
77 |
+
.printful-stats .printful-stats-item h4 .dashicons {
|
78 |
+
padding-top: 4px;
|
79 |
+
font-size: 30px;
|
80 |
+
width: 30px;
|
81 |
+
height: 30px;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
.printful-latest-orders {
|
86 |
+
display: table;
|
87 |
+
width: 100%;
|
88 |
+
margin-bottom: 50px;
|
89 |
+
}
|
90 |
+
.printful-latest-orders .row {
|
91 |
+
display: table-row;
|
92 |
+
}
|
93 |
+
.printful-latest-orders .row .cell {
|
94 |
+
display: table-cell;
|
95 |
+
}
|
96 |
+
|
97 |
+
.wrap h2.nav-tab-wrapper.printful-tabs {
|
98 |
+
margin-bottom: 15px;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
.printful-quick-links {
|
103 |
+
position: relative;
|
104 |
+
margin-bottom: 30px;
|
105 |
+
}
|
106 |
+
.printful-quick-links .printful-quick-links-item {
|
107 |
+
width: 120px;
|
108 |
+
background: #fff;
|
109 |
+
border: solid 1px #e1e1e1;
|
110 |
+
float: left;
|
111 |
+
padding: 20px;
|
112 |
+
margin-right: 25px;
|
113 |
+
margin-bottom: 25px;
|
114 |
+
text-align: center;
|
115 |
+
text-decoration: none;
|
116 |
+
}
|
117 |
+
.printful-quick-links .printful-quick-links-item .dashicons {
|
118 |
+
font-size: 40px;
|
119 |
+
width: 40px;
|
120 |
+
height: 40px;
|
121 |
+
text-decoration: none;
|
122 |
+
color: #444;
|
123 |
+
}
|
124 |
+
.printful-quick-links .printful-quick-links-item h4 {
|
125 |
+
text-decoration: none;
|
126 |
+
color: #444;
|
127 |
+
margin: 5px 0 0 0;
|
128 |
+
}
|
129 |
+
.printful-quick-links .printful-quick-links-item:hover {
|
130 |
+
cursor: pointer;
|
131 |
+
}
|
132 |
+
.printful-quick-links .printful-quick-links-item:hover .dashicons,
|
133 |
+
.printful-quick-links .printful-quick-links-item:hover h4 {
|
134 |
+
color: #0D72B2;
|
135 |
+
}
|
136 |
+
|
137 |
+
.printful-error {
|
138 |
+
margin-top: 20px;
|
139 |
+
}
|
140 |
+
|
141 |
+
.printful-notice {
|
142 |
+
background: #fff;
|
143 |
+
border-left: 4px solid #dc3232;
|
144 |
+
padding: 1px 12px;
|
145 |
+
margin: 10px 0 20px 0;
|
146 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
147 |
+
text-align: left;
|
148 |
+
}
|
149 |
+
.printful-notice li {
|
150 |
+
font-weight: bold;
|
151 |
+
margin-left: 20px;
|
152 |
+
list-style: disc;
|
153 |
+
}
|
154 |
+
|
155 |
+
.block-loader {
|
156 |
+
text-align: center;
|
157 |
+
padding: 20px 0;
|
158 |
+
line-height: 20px;
|
159 |
+
}
|
160 |
+
.block-loader .message {
|
161 |
+
padding-left: 10px;
|
162 |
+
line-height: 20px;
|
163 |
+
display: inline-block;
|
164 |
+
font-size: 16px;
|
165 |
+
}
|
166 |
+
.block-loader .loader {
|
167 |
+
vertical-align: top;
|
168 |
+
}
|
169 |
+
|
170 |
+
#wpfooter::after {
|
171 |
+
box-sizing: border-box;
|
172 |
+
content: "";
|
173 |
+
width: 64px;
|
174 |
+
left: 50%;
|
175 |
+
margin-left: -32px;
|
176 |
+
height: 28px;
|
177 |
+
position: absolute;
|
178 |
+
bottom: 0;
|
179 |
+
background: url("../images/printful-logo-footer.png") no-repeat bottom center;
|
180 |
+
background-size: 64px;
|
181 |
}
|
assets/css/global.css
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
-
.printful-toolbar .printful-toolbar-issues {
|
2 |
-
background-color: #d54e21;
|
3 |
-
display: inline-block;
|
4 |
-
padding: 0 5px !important;
|
5 |
-
border-radius: 10px !important;
|
6 |
-
line-height: 16px !important;
|
7 |
-
font-size: 11px !important;
|
8 |
-
color: #fff !important;
|
9 |
-
}
|
10 |
-
.printful-toolbar:hover .printful-toolbar-issues,
|
11 |
-
.printful-toolbar:active .printful-toolbar-issues,
|
12 |
-
.printful-toolbar.hover .printful-toolbar-issues
|
13 |
-
{
|
14 |
-
color: #fff !important;
|
15 |
-
}
|
16 |
-
|
17 |
-
#adminmenu .toplevel_page_printful-dashboard img {
|
18 |
-
width: 28px;
|
19 |
}
|
1 |
+
.printful-toolbar .printful-toolbar-issues {
|
2 |
+
background-color: #d54e21;
|
3 |
+
display: inline-block;
|
4 |
+
padding: 0 5px !important;
|
5 |
+
border-radius: 10px !important;
|
6 |
+
line-height: 16px !important;
|
7 |
+
font-size: 11px !important;
|
8 |
+
color: #fff !important;
|
9 |
+
}
|
10 |
+
.printful-toolbar:hover .printful-toolbar-issues,
|
11 |
+
.printful-toolbar:active .printful-toolbar-issues,
|
12 |
+
.printful-toolbar.hover .printful-toolbar-issues
|
13 |
+
{
|
14 |
+
color: #fff !important;
|
15 |
+
}
|
16 |
+
|
17 |
+
#adminmenu .toplevel_page_printful-dashboard img {
|
18 |
+
width: 28px;
|
19 |
}
|
assets/css/settings.css
CHANGED
@@ -1,46 +1,46 @@
|
|
1 |
-
.printful-setting-group {
|
2 |
-
overflow: hidden;
|
3 |
-
margin-bottom: 20px;
|
4 |
-
}
|
5 |
-
|
6 |
-
.printful-setting-group .input-text {
|
7 |
-
width: 400px;
|
8 |
-
}
|
9 |
-
|
10 |
-
.printful-setting-group .checkbox-group-item i {
|
11 |
-
color: #777;
|
12 |
-
}
|
13 |
-
|
14 |
-
.printful-submit .woocommerce-save-button {
|
15 |
-
float: left;
|
16 |
-
}
|
17 |
-
|
18 |
-
.printful-submit .loader-wrap {
|
19 |
-
display: inline-block;
|
20 |
-
padding: 4px 10px;
|
21 |
-
float: left;
|
22 |
-
}
|
23 |
-
|
24 |
-
.printful-submit .loader-wrap .loader {
|
25 |
-
display: none;
|
26 |
-
float: left;
|
27 |
-
}
|
28 |
-
|
29 |
-
.printful-submit .loader-wrap .dashicons {
|
30 |
-
font-size: 24px;
|
31 |
-
width: 24px;
|
32 |
-
height: 24px;
|
33 |
-
}
|
34 |
-
|
35 |
-
.printful-submit .loader-wrap .pass,
|
36 |
-
.printful-submit .loader-wrap .fail {
|
37 |
-
display: none;
|
38 |
-
float: left;
|
39 |
-
line-height: 24px;
|
40 |
-
}
|
41 |
-
|
42 |
-
.printful-setting-group .carrier-type {
|
43 |
-
font-weight: bold;
|
44 |
-
padding: 20px 0;
|
45 |
-
display: block;
|
46 |
}
|
1 |
+
.printful-setting-group {
|
2 |
+
overflow: hidden;
|
3 |
+
margin-bottom: 20px;
|
4 |
+
}
|
5 |
+
|
6 |
+
.printful-setting-group .input-text {
|
7 |
+
width: 400px;
|
8 |
+
}
|
9 |
+
|
10 |
+
.printful-setting-group .checkbox-group-item i {
|
11 |
+
color: #777;
|
12 |
+
}
|
13 |
+
|
14 |
+
.printful-submit .woocommerce-save-button {
|
15 |
+
float: left;
|
16 |
+
}
|
17 |
+
|
18 |
+
.printful-submit .loader-wrap {
|
19 |
+
display: inline-block;
|
20 |
+
padding: 4px 10px;
|
21 |
+
float: left;
|
22 |
+
}
|
23 |
+
|
24 |
+
.printful-submit .loader-wrap .loader {
|
25 |
+
display: none;
|
26 |
+
float: left;
|
27 |
+
}
|
28 |
+
|
29 |
+
.printful-submit .loader-wrap .dashicons {
|
30 |
+
font-size: 24px;
|
31 |
+
width: 24px;
|
32 |
+
height: 24px;
|
33 |
+
}
|
34 |
+
|
35 |
+
.printful-submit .loader-wrap .pass,
|
36 |
+
.printful-submit .loader-wrap .fail {
|
37 |
+
display: none;
|
38 |
+
float: left;
|
39 |
+
line-height: 24px;
|
40 |
+
}
|
41 |
+
|
42 |
+
.printful-setting-group .carrier-type {
|
43 |
+
font-weight: bold;
|
44 |
+
padding: 20px 0;
|
45 |
+
display: block;
|
46 |
}
|
assets/css/size-guide.css
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.pf-size-guide-modal-wrapper {
|
2 |
+
position: fixed;
|
3 |
+
z-index: 2147483648;
|
4 |
+
padding: 20px;
|
5 |
+
top: 0;
|
6 |
+
width: 100%;
|
7 |
+
height: 100%;
|
8 |
+
left: 0;
|
9 |
+
background: rgba(0, 0, 0, 0.6);
|
10 |
+
box-sizing: border-box;
|
11 |
+
}
|
12 |
+
|
13 |
+
.pf-size-guide-modal {
|
14 |
+
background-color: #fff;
|
15 |
+
width: 100%;
|
16 |
+
height: 100%;
|
17 |
+
max-width: 900px;
|
18 |
+
overflow: hidden;
|
19 |
+
overflow-y: auto;
|
20 |
+
position: relative;
|
21 |
+
margin: auto;
|
22 |
+
}
|
23 |
+
|
24 |
+
.pf-size-guide-modal__close {
|
25 |
+
height: 30px;
|
26 |
+
width: 30px;
|
27 |
+
cursor: pointer;
|
28 |
+
border: 0;
|
29 |
+
background: 0 0;
|
30 |
+
padding: 0;
|
31 |
+
-webkit-appearance: none;
|
32 |
+
float: right;
|
33 |
+
background: none !important;
|
34 |
+
}
|
35 |
+
|
36 |
+
.pf-size-guide-modal__header {
|
37 |
+
width: 100%;
|
38 |
+
box-sizing: border-box;
|
39 |
+
padding: 15px;
|
40 |
+
}
|
41 |
+
|
42 |
+
.pf-size-guide-modal__title {
|
43 |
+
float: left;
|
44 |
+
font-weight: bold;
|
45 |
+
margin: 0;
|
46 |
+
clear: none;
|
47 |
+
}
|
48 |
+
|
49 |
+
.pf-size-guide-modal__close img {
|
50 |
+
height: 30px;
|
51 |
+
width: 30px;
|
52 |
+
}
|
53 |
+
|
54 |
+
.pf-size-guide-modal__content {
|
55 |
+
padding: 15px;
|
56 |
+
}
|
57 |
+
|
58 |
+
.pf-size-guide-modal__content h4 {
|
59 |
+
margin: 24px 0 16px;
|
60 |
+
}
|
61 |
+
.pf-size-guide-modal__content p {
|
62 |
+
margin: 0 0 10px;
|
63 |
+
}
|
64 |
+
.pf-size-guide-modal-size-chart {
|
65 |
+
overflow-x: auto;
|
66 |
+
}
|
67 |
+
|
68 |
+
.pf-product-size-guide__tabs {
|
69 |
+
white-space: nowrap;
|
70 |
+
}
|
71 |
+
|
72 |
+
.pf-product-size-guide__tabs,
|
73 |
+
.pf-size-guide-modal-size-chart__tabs {
|
74 |
+
list-style: none;
|
75 |
+
padding: 0;
|
76 |
+
margin: 0;
|
77 |
+
box-shadow: inset 0 -1px 0 0 #E5E5E5;
|
78 |
+
}
|
79 |
+
|
80 |
+
.pf-product-size-guide__tab {
|
81 |
+
cursor: pointer;
|
82 |
+
vertical-align: bottom;
|
83 |
+
margin-right: 8px;
|
84 |
+
display: inline-block;
|
85 |
+
padding: 12px 16px;
|
86 |
+
border: 1px solid #F8F8F8;
|
87 |
+
border-bottom: 1px solid #E5E5E5;
|
88 |
+
}
|
89 |
+
|
90 |
+
.pf-product-size-guide__tab.pf-product-size-guide__tab--active {
|
91 |
+
border: solid 1px #E5E5E5;
|
92 |
+
border-bottom: none;
|
93 |
+
}
|
94 |
+
|
95 |
+
.pf-size-guide-modal-size-chart__tab {
|
96 |
+
font-size: 15px;
|
97 |
+
font-weight: bold;
|
98 |
+
border: solid 1px transparent;
|
99 |
+
cursor: pointer;
|
100 |
+
vertical-align: bottom;
|
101 |
+
margin-right: 8px;
|
102 |
+
display: inline-block;
|
103 |
+
padding: 12px 8px;
|
104 |
+
text-transform: capitalize;
|
105 |
+
}
|
106 |
+
.pf-size-guide-modal-size-chart__tab.pf-size-guide-modal-size-chart__tab--active {
|
107 |
+
box-shadow: inset 0 -3px #222;
|
108 |
+
font-weight: bold;
|
109 |
+
}
|
110 |
+
|
111 |
+
.pf-size-guide-modal-measurements {
|
112 |
+
padding: 15px 0;
|
113 |
+
}
|
114 |
+
|
115 |
+
.pf-size-guide-modal-measurements__description {
|
116 |
+
float: left;
|
117 |
+
width: 65%;
|
118 |
+
position: relative;
|
119 |
+
}
|
120 |
+
|
121 |
+
.pf-size-guide-modal-measurements__image {
|
122 |
+
position: relative;
|
123 |
+
width: 35%;
|
124 |
+
padding: 5px;
|
125 |
+
text-align: center;
|
126 |
+
float: left;
|
127 |
+
}
|
128 |
+
|
129 |
+
@media only screen and (max-width: 960px) {
|
130 |
+
.pf-size-guide-modal-measurements__image,
|
131 |
+
.pf-size-guide-modal-measurements__description {
|
132 |
+
float: none;
|
133 |
+
display: block;
|
134 |
+
width: 100%;
|
135 |
+
}
|
136 |
+
|
137 |
+
.pf-product-size-guide__tabs {
|
138 |
+
overflow-x: scroll;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
.pf-size-guide-modal-size-chart__table {
|
143 |
+
border-collapse: collapse;
|
144 |
+
table-layout: fixed;
|
145 |
+
width: 100%;
|
146 |
+
overflow-x: auto;
|
147 |
+
white-space: nowrap;
|
148 |
+
}
|
149 |
+
|
150 |
+
.pf-size-guide-modal-size-chart__table thead {
|
151 |
+
text-transform: uppercase;
|
152 |
+
font-weight: bold;
|
153 |
+
}
|
154 |
+
|
155 |
+
.pf-size-guide-modal-size-chart__table tr {
|
156 |
+
border: none;
|
157 |
+
border-collapse: collapse;
|
158 |
+
}
|
159 |
+
|
160 |
+
.pf-size-guide-modal-size-chart__table td {
|
161 |
+
border: none;
|
162 |
+
border-bottom: 1px solid #E5E5E5;
|
163 |
+
font-size: 16px;
|
164 |
+
text-transform: uppercase;
|
165 |
+
padding: 12px 8px;
|
166 |
+
}
|
167 |
+
|
168 |
+
.pf-size-guide-modal-clear {
|
169 |
+
clear: both;
|
170 |
+
}
|
171 |
+
|
assets/css/status.css
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
.pass {
|
2 |
-
font-weight: bold;
|
3 |
-
color: green;
|
4 |
-
}
|
5 |
-
.fail {
|
6 |
-
font-weight: bold;
|
7 |
-
color: red;
|
8 |
-
}
|
9 |
-
.warning {
|
10 |
-
font-weight: bold;
|
11 |
-
color: #cab827;
|
12 |
-
}
|
13 |
-
.printful-status .col-status {
|
14 |
-
width: 10%;
|
15 |
-
}
|
16 |
-
.printful-status .col-desc {
|
17 |
-
width: 57%;
|
18 |
-
}
|
19 |
-
.printful-status tbody tr:first-child td {
|
20 |
-
font-weight: bold;
|
21 |
}
|
1 |
+
.pass {
|
2 |
+
font-weight: bold;
|
3 |
+
color: green;
|
4 |
+
}
|
5 |
+
.fail {
|
6 |
+
font-weight: bold;
|
7 |
+
color: red;
|
8 |
+
}
|
9 |
+
.warning {
|
10 |
+
font-weight: bold;
|
11 |
+
color: #cab827;
|
12 |
+
}
|
13 |
+
.printful-status .col-status {
|
14 |
+
width: 10%;
|
15 |
+
}
|
16 |
+
.printful-status .col-desc {
|
17 |
+
width: 57%;
|
18 |
+
}
|
19 |
+
.printful-status tbody tr:first-child td {
|
20 |
+
font-weight: bold;
|
21 |
}
|
assets/css/support.css
CHANGED
@@ -1,62 +1,62 @@
|
|
1 |
-
.support-report-wrap {
|
2 |
-
background-color: #fff;
|
3 |
-
padding: 20px;
|
4 |
-
margin: 20px 0;
|
5 |
-
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
6 |
-
border-left: #0073aa 4px solid;
|
7 |
-
}
|
8 |
-
|
9 |
-
.support-report-wrap p {
|
10 |
-
margin-top: 0;
|
11 |
-
}
|
12 |
-
|
13 |
-
.support-report-wrap .support-report {
|
14 |
-
width: 100%;
|
15 |
-
height: 100px;
|
16 |
-
font-family: monospace;
|
17 |
-
margin-bottom: 10px;
|
18 |
-
background: #efefef;
|
19 |
-
}
|
20 |
-
|
21 |
-
.support-info-wrap {
|
22 |
-
margin-top: 40px;
|
23 |
-
box-sizing: border-box;
|
24 |
-
|
25 |
-
}
|
26 |
-
|
27 |
-
.support-info-wrap .support-info-block {
|
28 |
-
box-sizing: border-box;
|
29 |
-
padding: 20px;
|
30 |
-
background: #fff;
|
31 |
-
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
32 |
-
margin-bottom: 20px;
|
33 |
-
}
|
34 |
-
|
35 |
-
.support-info-wrap .support-info-block h3 {
|
36 |
-
text-align: center;
|
37 |
-
margin-top: 10px;
|
38 |
-
}
|
39 |
-
|
40 |
-
.support-info-wrap .support-info-block .btn-wrap {
|
41 |
-
margin-top: 20px;
|
42 |
-
text-align: center;
|
43 |
-
}
|
44 |
-
|
45 |
-
@media (min-width: 768px) {
|
46 |
-
|
47 |
-
.support-info-wrap {
|
48 |
-
justify-content: space-between;
|
49 |
-
display: flex;
|
50 |
-
}
|
51 |
-
|
52 |
-
.support-info-wrap .support-info-block {
|
53 |
-
width: 32%;
|
54 |
-
}
|
55 |
-
|
56 |
-
.support-info-wrap .support-info-block:first-child {
|
57 |
-
|
58 |
-
}
|
59 |
-
.support-info-wrap .support-info-block:last-child {
|
60 |
-
|
61 |
-
}
|
62 |
}
|
1 |
+
.support-report-wrap {
|
2 |
+
background-color: #fff;
|
3 |
+
padding: 20px;
|
4 |
+
margin: 20px 0;
|
5 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
6 |
+
border-left: #0073aa 4px solid;
|
7 |
+
}
|
8 |
+
|
9 |
+
.support-report-wrap p {
|
10 |
+
margin-top: 0;
|
11 |
+
}
|
12 |
+
|
13 |
+
.support-report-wrap .support-report {
|
14 |
+
width: 100%;
|
15 |
+
height: 100px;
|
16 |
+
font-family: monospace;
|
17 |
+
margin-bottom: 10px;
|
18 |
+
background: #efefef;
|
19 |
+
}
|
20 |
+
|
21 |
+
.support-info-wrap {
|
22 |
+
margin-top: 40px;
|
23 |
+
box-sizing: border-box;
|
24 |
+
|
25 |
+
}
|
26 |
+
|
27 |
+
.support-info-wrap .support-info-block {
|
28 |
+
box-sizing: border-box;
|
29 |
+
padding: 20px;
|
30 |
+
background: #fff;
|
31 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
32 |
+
margin-bottom: 20px;
|
33 |
+
}
|
34 |
+
|
35 |
+
.support-info-wrap .support-info-block h3 {
|
36 |
+
text-align: center;
|
37 |
+
margin-top: 10px;
|
38 |
+
}
|
39 |
+
|
40 |
+
.support-info-wrap .support-info-block .btn-wrap {
|
41 |
+
margin-top: 20px;
|
42 |
+
text-align: center;
|
43 |
+
}
|
44 |
+
|
45 |
+
@media (min-width: 768px) {
|
46 |
+
|
47 |
+
.support-info-wrap {
|
48 |
+
justify-content: space-between;
|
49 |
+
display: flex;
|
50 |
+
}
|
51 |
+
|
52 |
+
.support-info-wrap .support-info-block {
|
53 |
+
width: 32%;
|
54 |
+
}
|
55 |
+
|
56 |
+
.support-info-wrap .support-info-block:first-child {
|
57 |
+
|
58 |
+
}
|
59 |
+
.support-info-wrap .support-info-block:last-child {
|
60 |
+
|
61 |
+
}
|
62 |
}
|
assets/images/connect.svg
CHANGED
@@ -1,74 +1,74 @@
|
|
1 |
-
<svg xmlns="http://www.w3.org/2000/svg" width="408" height="177" viewBox="0 0 408 177">
|
2 |
-
<g fill="none" fill-rule="evenodd" transform="translate(1 1)">
|
3 |
-
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M299 120h107v8H299zM0 120h107v8H0z"/>
|
4 |
-
<path stroke="#D1D3D4" d="M197.5 21V10.2c0-5.5-4.1-9.8-9.6-9.8h-124c-5.5 0-10.4 4.2-10.4 9.8V87M208.5 21V10.2c0-5.5 4.9-9.8 10.4-9.8h124c5.5 0 9.6 4.2 9.6 9.8V87"/>
|
5 |
-
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M5 48h97v72H5z"/>
|
6 |
-
<g fill-rule="nonzero">
|
7 |
-
<path fill="#9B5C8F" d="M27.104 70h44.77C74.706 70 77 72.312 77 75.168v17.225c0 2.856-2.293 5.168-5.127 5.168H55.82L58.022 103l-9.691-5.44H27.127C24.294 97.56 22 95.25 22 92.394V75.168C21.978 72.334 24.27 70 27.104 70z"/>
|
8 |
-
<path fill="#FFF" d="M25.389 74.664c.316-.431.79-.658 1.422-.703 1.152-.091 1.807.453 1.965 1.633.7 4.743 1.468 8.76 2.28 12.05l4.946-9.463c.451-.862 1.016-1.316 1.693-1.361.994-.068 1.603.567 1.852 1.906.565 3.017 1.287 5.582 2.145 7.76.587-5.763 1.58-9.916 2.98-12.48.34-.635.836-.953 1.491-.998.52-.046.994.113 1.423.453.429.34.655.772.7 1.294.022.408-.045.749-.226 1.09-.88 1.633-1.603 4.378-2.19 8.19-.565 3.699-.768 6.58-.633 8.646.046.567-.045 1.066-.27 1.497-.272.5-.678.772-1.197.817-.588.046-1.197-.227-1.784-.84-2.1-2.155-3.771-5.377-4.99-9.666a425.409 425.409 0 0 0-3.252 6.535c-1.333 2.564-2.462 3.88-3.41 3.948-.61.046-1.13-.476-1.58-1.565-1.152-2.973-2.394-8.714-3.726-17.223-.09-.59.044-1.112.36-1.52zm48.526 3.563c-.813-1.43-2.01-2.292-3.613-2.633a5.904 5.904 0 0 0-1.22-.136c-2.167 0-3.928 1.135-5.306 3.404-1.174 1.929-1.76 4.062-1.76 6.399 0 1.747.36 3.244 1.083 4.493.813 1.43 2.01 2.291 3.613 2.632.429.09.835.136 1.22.136 2.19 0 3.95-1.135 5.306-3.404 1.174-1.951 1.761-4.084 1.761-6.421.023-1.77-.361-3.245-1.084-4.47zm-2.845 6.285c-.316 1.498-.88 2.61-1.716 3.358-.655.59-1.265.84-1.83.726-.541-.113-.993-.59-1.331-1.475a5.778 5.778 0 0 1-.407-2.065c0-.567.045-1.134.158-1.656a7.357 7.357 0 0 1 1.197-2.7c.745-1.112 1.535-1.566 2.348-1.407.542.113.994.59 1.333 1.475.27.703.406 1.407.406 2.065 0 .59-.045 1.157-.158 1.679zm-11.29-6.285c-.813-1.43-2.033-2.292-3.613-2.633a5.902 5.902 0 0 0-1.22-.136c-2.168 0-3.929 1.135-5.306 3.404-1.174 1.929-1.762 4.062-1.762 6.399 0 1.747.362 3.244 1.084 4.493.813 1.43 2.01 2.291 3.613 2.632.43.09.835.136 1.22.136 2.19 0 3.951-1.135 5.306-3.404 1.174-1.951 1.761-4.084 1.761-6.421 0-1.77-.361-3.245-1.084-4.47zm-2.868 6.285c-.316 1.498-.881 2.61-1.716 3.358-.655.59-1.265.84-1.83.726-.541-.113-.993-.59-1.332-1.475a5.787 5.787 0 0 1-.406-2.065c0-.567.045-1.134.158-1.656a7.354 7.354 0 0 1 1.197-2.7c.745-1.112 1.535-1.566 2.348-1.407.542.113.994.59 1.332 1.475.272.703.407 1.407.407 2.065a6.726 6.726 0 0 1-.158 1.679z"/>
|
9 |
-
</g>
|
10 |
-
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M304 48h97v72h-97z"/>
|
11 |
-
<g fill-rule="nonzero">
|
12 |
-
<path fill="#F2C994" d="M320 98l17.5-30L355 98z"/>
|
13 |
-
<path fill="#ED4642" d="M336 98l17.5-30L371 98z"/>
|
14 |
-
<path fill="#17BCB5" d="M352 98l17.5-30L387 98z"/>
|
15 |
-
<path fill="#16342F" d="M352 98h19l-9.5-16z"/>
|
16 |
-
<path fill="#DF392F" d="M336 98h19l-9.5-16z"/>
|
17 |
-
<path fill="#15291B" d="M352 98h3l-1.5-3z"/>
|
18 |
-
</g>
|
19 |
-
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M155 21h97v124h-97z"/>
|
20 |
-
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M150 142h107v33H150z"/>
|
21 |
-
<path stroke="#D1D3D4" d="M162.5 161.8l1.3-3.4 2 3.6 5.3-9.2 4 9.2 2.7-4.6 3.3 2.6"/>
|
22 |
-
<path stroke="#231F20" d="M161.5 148.5h20v20h-20zM187.5 148.5h61v20h-61z"/>
|
23 |
-
<circle cx="191.2" cy="33.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
24 |
-
<path stroke="#FFF" d="M191.2 33.8l.7-3.8"/>
|
25 |
-
<circle cx="191.2" cy="44.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
26 |
-
<path stroke="#FFF" d="M191.2 44.8l2.3 3"/>
|
27 |
-
<circle cx="191.2" cy="55.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
28 |
-
<path stroke="#FFF" d="M191.2 55.8l-3 2.3"/>
|
29 |
-
<circle cx="191.2" cy="66.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
30 |
-
<path stroke="#FFF" d="M191.2 66.8l2.3 3"/>
|
31 |
-
<circle cx="191.2" cy="77.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
32 |
-
<path stroke="#FFF" d="M191.2 77.8l3.6 1.2"/>
|
33 |
-
<path fill="#F1F2F2" fill-rule="nonzero" stroke="#231F20" d="M183.5 87.5h7v3h-7zM193.5 87.5h7v3h-7zM203.5 87.5h7v3h-7zM213.5 87.5h7v3h-7zM223.5 87.5h7v3h-7z"/>
|
34 |
-
<path fill="#F2C994" fill-rule="nonzero" stroke="#231F20" d="M233.5 87.5h7v3h-7z"/>
|
35 |
-
<path stroke="#231F20" stroke-width="2" d="M184 30v52"/>
|
36 |
-
<circle cx="214.2" cy="33.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
37 |
-
<path stroke="#FFF" d="M214.2 33.8l2.3 3"/>
|
38 |
-
<circle cx="214.2" cy="44.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
39 |
-
<path stroke="#FFF" d="M214.2 44.8l3-2.4"/>
|
40 |
-
<circle cx="214.2" cy="55.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
41 |
-
<path stroke="#FFF" d="M214.2 55.8l2.3 3"/>
|
42 |
-
<circle cx="214.2" cy="66.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
43 |
-
<path stroke="#FFF" d="M214.2 66.8l-3 2.3"/>
|
44 |
-
<circle cx="214.2" cy="77.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
45 |
-
<path stroke="#FFF" d="M214.2 77.8l2.3 3"/>
|
46 |
-
<path stroke="#231F20" stroke-width="2" d="M207 30v52"/>
|
47 |
-
<circle cx="237.2" cy="33.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
48 |
-
<path stroke="#FFF" d="M237.2 33.8l3.7.8"/>
|
49 |
-
<circle cx="237.2" cy="44.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
50 |
-
<path stroke="#FFF" d="M237.2 44.8l2.3 3"/>
|
51 |
-
<circle cx="237.2" cy="55.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
52 |
-
<path stroke="#FFF" d="M237.2 55.8l.3 3.8"/>
|
53 |
-
<circle cx="237.2" cy="66.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
54 |
-
<path stroke="#FFF" d="M237.2 66.8l3.4-1.7"/>
|
55 |
-
<circle cx="237.2" cy="77.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
56 |
-
<path stroke="#FFF" d="M237.2 77.8l2.3 3"/>
|
57 |
-
<path stroke="#231F20" stroke-width="2" d="M230 30v52M184 96v34M207 96v34"/>
|
58 |
-
<path fill="#F1F2F2" fill-rule="nonzero" stroke="#231F20" d="M179.5 109.5h9v3h-9zM202.5 125.5h9v4h-9z"/>
|
59 |
-
<path stroke="#231F20" stroke-width="2" d="M230 96v34"/>
|
60 |
-
<path fill="#F1F2F2" fill-rule="nonzero" stroke="#231F20" d="M225.5 114.5h9v4h-9z"/>
|
61 |
-
<circle cx="169.5" cy="35.8" r="5" fill="#F2C994" fill-rule="nonzero" stroke="#231F20" stroke-width="2"/>
|
62 |
-
<circle cx="169.5" cy="48.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
63 |
-
<circle cx="169.5" cy="59.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
64 |
-
<circle cx="169.5" cy="70.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
65 |
-
<circle cx="169.5" cy="81.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
66 |
-
<circle cx="169.5" cy="99.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
67 |
-
<circle cx="169.5" cy="113.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
68 |
-
<circle cx="169.5" cy="127.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
69 |
-
<circle cx="194.2" cy="152.8" r="2" fill="#F2C994" fill-rule="nonzero"/>
|
70 |
-
<circle cx="210.2" cy="162.8" r="2" fill="#F2C994" fill-rule="nonzero"/>
|
71 |
-
<path stroke="#231F20" d="M187 156.5h61"/>
|
72 |
-
<circle cx="239.2" cy="159.8" r="2" fill="#F2C994" fill-rule="nonzero"/>
|
73 |
-
</g>
|
74 |
-
</svg>
|
1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="408" height="177" viewBox="0 0 408 177">
|
2 |
+
<g fill="none" fill-rule="evenodd" transform="translate(1 1)">
|
3 |
+
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M299 120h107v8H299zM0 120h107v8H0z"/>
|
4 |
+
<path stroke="#D1D3D4" d="M197.5 21V10.2c0-5.5-4.1-9.8-9.6-9.8h-124c-5.5 0-10.4 4.2-10.4 9.8V87M208.5 21V10.2c0-5.5 4.9-9.8 10.4-9.8h124c5.5 0 9.6 4.2 9.6 9.8V87"/>
|
5 |
+
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M5 48h97v72H5z"/>
|
6 |
+
<g fill-rule="nonzero">
|
7 |
+
<path fill="#9B5C8F" d="M27.104 70h44.77C74.706 70 77 72.312 77 75.168v17.225c0 2.856-2.293 5.168-5.127 5.168H55.82L58.022 103l-9.691-5.44H27.127C24.294 97.56 22 95.25 22 92.394V75.168C21.978 72.334 24.27 70 27.104 70z"/>
|
8 |
+
<path fill="#FFF" d="M25.389 74.664c.316-.431.79-.658 1.422-.703 1.152-.091 1.807.453 1.965 1.633.7 4.743 1.468 8.76 2.28 12.05l4.946-9.463c.451-.862 1.016-1.316 1.693-1.361.994-.068 1.603.567 1.852 1.906.565 3.017 1.287 5.582 2.145 7.76.587-5.763 1.58-9.916 2.98-12.48.34-.635.836-.953 1.491-.998.52-.046.994.113 1.423.453.429.34.655.772.7 1.294.022.408-.045.749-.226 1.09-.88 1.633-1.603 4.378-2.19 8.19-.565 3.699-.768 6.58-.633 8.646.046.567-.045 1.066-.27 1.497-.272.5-.678.772-1.197.817-.588.046-1.197-.227-1.784-.84-2.1-2.155-3.771-5.377-4.99-9.666a425.409 425.409 0 0 0-3.252 6.535c-1.333 2.564-2.462 3.88-3.41 3.948-.61.046-1.13-.476-1.58-1.565-1.152-2.973-2.394-8.714-3.726-17.223-.09-.59.044-1.112.36-1.52zm48.526 3.563c-.813-1.43-2.01-2.292-3.613-2.633a5.904 5.904 0 0 0-1.22-.136c-2.167 0-3.928 1.135-5.306 3.404-1.174 1.929-1.76 4.062-1.76 6.399 0 1.747.36 3.244 1.083 4.493.813 1.43 2.01 2.291 3.613 2.632.429.09.835.136 1.22.136 2.19 0 3.95-1.135 5.306-3.404 1.174-1.951 1.761-4.084 1.761-6.421.023-1.77-.361-3.245-1.084-4.47zm-2.845 6.285c-.316 1.498-.88 2.61-1.716 3.358-.655.59-1.265.84-1.83.726-.541-.113-.993-.59-1.331-1.475a5.778 5.778 0 0 1-.407-2.065c0-.567.045-1.134.158-1.656a7.357 7.357 0 0 1 1.197-2.7c.745-1.112 1.535-1.566 2.348-1.407.542.113.994.59 1.333 1.475.27.703.406 1.407.406 2.065 0 .59-.045 1.157-.158 1.679zm-11.29-6.285c-.813-1.43-2.033-2.292-3.613-2.633a5.902 5.902 0 0 0-1.22-.136c-2.168 0-3.929 1.135-5.306 3.404-1.174 1.929-1.762 4.062-1.762 6.399 0 1.747.362 3.244 1.084 4.493.813 1.43 2.01 2.291 3.613 2.632.43.09.835.136 1.22.136 2.19 0 3.951-1.135 5.306-3.404 1.174-1.951 1.761-4.084 1.761-6.421 0-1.77-.361-3.245-1.084-4.47zm-2.868 6.285c-.316 1.498-.881 2.61-1.716 3.358-.655.59-1.265.84-1.83.726-.541-.113-.993-.59-1.332-1.475a5.787 5.787 0 0 1-.406-2.065c0-.567.045-1.134.158-1.656a7.354 7.354 0 0 1 1.197-2.7c.745-1.112 1.535-1.566 2.348-1.407.542.113.994.59 1.332 1.475.272.703.407 1.407.407 2.065a6.726 6.726 0 0 1-.158 1.679z"/>
|
9 |
+
</g>
|
10 |
+
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M304 48h97v72h-97z"/>
|
11 |
+
<g fill-rule="nonzero">
|
12 |
+
<path fill="#F2C994" d="M320 98l17.5-30L355 98z"/>
|
13 |
+
<path fill="#ED4642" d="M336 98l17.5-30L371 98z"/>
|
14 |
+
<path fill="#17BCB5" d="M352 98l17.5-30L387 98z"/>
|
15 |
+
<path fill="#16342F" d="M352 98h19l-9.5-16z"/>
|
16 |
+
<path fill="#DF392F" d="M336 98h19l-9.5-16z"/>
|
17 |
+
<path fill="#15291B" d="M352 98h3l-1.5-3z"/>
|
18 |
+
</g>
|
19 |
+
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M155 21h97v124h-97z"/>
|
20 |
+
<path fill="#FFF" fill-rule="nonzero" stroke="#231F20" stroke-width="2" d="M150 142h107v33H150z"/>
|
21 |
+
<path stroke="#D1D3D4" d="M162.5 161.8l1.3-3.4 2 3.6 5.3-9.2 4 9.2 2.7-4.6 3.3 2.6"/>
|
22 |
+
<path stroke="#231F20" d="M161.5 148.5h20v20h-20zM187.5 148.5h61v20h-61z"/>
|
23 |
+
<circle cx="191.2" cy="33.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
24 |
+
<path stroke="#FFF" d="M191.2 33.8l.7-3.8"/>
|
25 |
+
<circle cx="191.2" cy="44.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
26 |
+
<path stroke="#FFF" d="M191.2 44.8l2.3 3"/>
|
27 |
+
<circle cx="191.2" cy="55.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
28 |
+
<path stroke="#FFF" d="M191.2 55.8l-3 2.3"/>
|
29 |
+
<circle cx="191.2" cy="66.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
30 |
+
<path stroke="#FFF" d="M191.2 66.8l2.3 3"/>
|
31 |
+
<circle cx="191.2" cy="77.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
32 |
+
<path stroke="#FFF" d="M191.2 77.8l3.6 1.2"/>
|
33 |
+
<path fill="#F1F2F2" fill-rule="nonzero" stroke="#231F20" d="M183.5 87.5h7v3h-7zM193.5 87.5h7v3h-7zM203.5 87.5h7v3h-7zM213.5 87.5h7v3h-7zM223.5 87.5h7v3h-7z"/>
|
34 |
+
<path fill="#F2C994" fill-rule="nonzero" stroke="#231F20" d="M233.5 87.5h7v3h-7z"/>
|
35 |
+
<path stroke="#231F20" stroke-width="2" d="M184 30v52"/>
|
36 |
+
<circle cx="214.2" cy="33.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
37 |
+
<path stroke="#FFF" d="M214.2 33.8l2.3 3"/>
|
38 |
+
<circle cx="214.2" cy="44.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
39 |
+
<path stroke="#FFF" d="M214.2 44.8l3-2.4"/>
|
40 |
+
<circle cx="214.2" cy="55.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
41 |
+
<path stroke="#FFF" d="M214.2 55.8l2.3 3"/>
|
42 |
+
<circle cx="214.2" cy="66.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
43 |
+
<path stroke="#FFF" d="M214.2 66.8l-3 2.3"/>
|
44 |
+
<circle cx="214.2" cy="77.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
45 |
+
<path stroke="#FFF" d="M214.2 77.8l2.3 3"/>
|
46 |
+
<path stroke="#231F20" stroke-width="2" d="M207 30v52"/>
|
47 |
+
<circle cx="237.2" cy="33.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
48 |
+
<path stroke="#FFF" d="M237.2 33.8l3.7.8"/>
|
49 |
+
<circle cx="237.2" cy="44.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
50 |
+
<path stroke="#FFF" d="M237.2 44.8l2.3 3"/>
|
51 |
+
<circle cx="237.2" cy="55.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
52 |
+
<path stroke="#FFF" d="M237.2 55.8l.3 3.8"/>
|
53 |
+
<circle cx="237.2" cy="66.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
54 |
+
<path stroke="#FFF" d="M237.2 66.8l3.4-1.7"/>
|
55 |
+
<circle cx="237.2" cy="77.8" r="4" fill="#D1D3D4" fill-rule="nonzero"/>
|
56 |
+
<path stroke="#FFF" d="M237.2 77.8l2.3 3"/>
|
57 |
+
<path stroke="#231F20" stroke-width="2" d="M230 30v52M184 96v34M207 96v34"/>
|
58 |
+
<path fill="#F1F2F2" fill-rule="nonzero" stroke="#231F20" d="M179.5 109.5h9v3h-9zM202.5 125.5h9v4h-9z"/>
|
59 |
+
<path stroke="#231F20" stroke-width="2" d="M230 96v34"/>
|
60 |
+
<path fill="#F1F2F2" fill-rule="nonzero" stroke="#231F20" d="M225.5 114.5h9v4h-9z"/>
|
61 |
+
<circle cx="169.5" cy="35.8" r="5" fill="#F2C994" fill-rule="nonzero" stroke="#231F20" stroke-width="2"/>
|
62 |
+
<circle cx="169.5" cy="48.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
63 |
+
<circle cx="169.5" cy="59.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
64 |
+
<circle cx="169.5" cy="70.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
65 |
+
<circle cx="169.5" cy="81.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
66 |
+
<circle cx="169.5" cy="99.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
67 |
+
<circle cx="169.5" cy="113.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
68 |
+
<circle cx="169.5" cy="127.8" r="3" fill="#D1D3D4" fill-rule="nonzero"/>
|
69 |
+
<circle cx="194.2" cy="152.8" r="2" fill="#F2C994" fill-rule="nonzero"/>
|
70 |
+
<circle cx="210.2" cy="162.8" r="2" fill="#F2C994" fill-rule="nonzero"/>
|
71 |
+
<path stroke="#231F20" d="M187 156.5h61"/>
|
72 |
+
<circle cx="239.2" cy="159.8" r="2" fill="#F2C994" fill-rule="nonzero"/>
|
73 |
+
</g>
|
74 |
+
</svg>
|
assets/js/block-loader.js
CHANGED
@@ -1,22 +1,22 @@
|
|
1 |
-
var Printful_Block_Loader;
|
2 |
-
|
3 |
-
(function () {
|
4 |
-
'use strict';
|
5 |
-
|
6 |
-
Printful_Block_Loader = {
|
7 |
-
load: function (ajax_url, block) {
|
8 |
-
|
9 |
-
block = jQuery('#' + block);
|
10 |
-
if (block.length > 0) {
|
11 |
-
|
12 |
-
jQuery.ajax({
|
13 |
-
type: "GET",
|
14 |
-
url: ajax_url,
|
15 |
-
success: function (response) {
|
16 |
-
block.html(response);
|
17 |
-
}
|
18 |
-
});
|
19 |
-
}
|
20 |
-
}
|
21 |
-
};
|
22 |
})();
|
1 |
+
var Printful_Block_Loader;
|
2 |
+
|
3 |
+
(function () {
|
4 |
+
'use strict';
|
5 |
+
|
6 |
+
Printful_Block_Loader = {
|
7 |
+
load: function (ajax_url, block) {
|
8 |
+
|
9 |
+
block = jQuery('#' + block);
|
10 |
+
if (block.length > 0) {
|
11 |
+
|
12 |
+
jQuery.ajax({
|
13 |
+
type: "GET",
|
14 |
+
url: ajax_url,
|
15 |
+
success: function (response) {
|
16 |
+
block.html(response);
|
17 |
+
}
|
18 |
+
});
|
19 |
+
}
|
20 |
+
}
|
21 |
+
};
|
22 |
})();
|
assets/js/connect.js
CHANGED
@@ -1,60 +1,60 @@
|
|
1 |
-
var Printful_Connect;
|
2 |
-
|
3 |
-
(function () {
|
4 |
-
'use strict';
|
5 |
-
|
6 |
-
Printful_Connect = {
|
7 |
-
interval: 0,
|
8 |
-
ajax_url: '',
|
9 |
-
init: function (ajax_url) {
|
10 |
-
this.ajax_url = ajax_url;
|
11 |
-
this.loader();
|
12 |
-
this.listen_status();
|
13 |
-
this.listen_auth_return();
|
14 |
-
},
|
15 |
-
loader: function () {
|
16 |
-
jQuery('.printful-connect-button').click(function () {
|
17 |
-
jQuery(this).hide();
|
18 |
-
jQuery(this).siblings('.loader').removeClass('hidden');
|
19 |
-
|
20 |
-
setTimeout(function() {
|
21 |
-
Printful_Connect.hide_loader();
|
22 |
-
}, 60000); //hide the loader after a minute, assume failure
|
23 |
-
});
|
24 |
-
},
|
25 |
-
hide_loader: function() {
|
26 |
-
var button = jQuery('.printful-connect-button');
|
27 |
-
button.show();
|
28 |
-
button.siblings('.loader').addClass('hidden');
|
29 |
-
},
|
30 |
-
listen_status: function () {
|
31 |
-
this.interval = setInterval(this.get_status.bind(this), 10000); //check status every 10 secs
|
32 |
-
},
|
33 |
-
get_status: function () {
|
34 |
-
var interval = this.interval;
|
35 |
-
jQuery.ajax( {
|
36 |
-
type: "GET",
|
37 |
-
url: this.ajax_url,
|
38 |
-
success: function( response ) {
|
39 |
-
if (response === 'OK') {
|
40 |
-
clearInterval(interval);
|
41 |
-
Printful_Connect.send_return_message();
|
42 |
-
}
|
43 |
-
}
|
44 |
-
});
|
45 |
-
},
|
46 |
-
listen_auth_return: function () {
|
47 |
-
var intercom = Intercom.getInstance();
|
48 |
-
intercom.on('printful-auth', function (data) {
|
49 |
-
if (data.success === true) {
|
50 |
-
location.reload();
|
51 |
-
}
|
52 |
-
});
|
53 |
-
},
|
54 |
-
send_return_message: function () {
|
55 |
-
var intercom = Intercom.getInstance();
|
56 |
-
intercom.emit('printful-auth', {success: true});
|
57 |
-
window.top.close();
|
58 |
-
}
|
59 |
-
};
|
60 |
})();
|
1 |
+
var Printful_Connect;
|
2 |
+
|
3 |
+
(function () {
|
4 |
+
'use strict';
|
5 |
+
|
6 |
+
Printful_Connect = {
|
7 |
+
interval: 0,
|
8 |
+
ajax_url: '',
|
9 |
+
init: function (ajax_url) {
|
10 |
+
this.ajax_url = ajax_url;
|
11 |
+
this.loader();
|
12 |
+
this.listen_status();
|
13 |
+
this.listen_auth_return();
|
14 |
+
},
|
15 |
+
loader: function () {
|
16 |
+
jQuery('.printful-connect-button').click(function () {
|
17 |
+
jQuery(this).hide();
|
18 |
+
jQuery(this).siblings('.loader').removeClass('hidden');
|
19 |
+
|
20 |
+
setTimeout(function() {
|
21 |
+
Printful_Connect.hide_loader();
|
22 |
+
}, 60000); //hide the loader after a minute, assume failure
|
23 |
+
});
|
24 |
+
},
|
25 |
+
hide_loader: function() {
|
26 |
+
var button = jQuery('.printful-connect-button');
|
27 |
+
button.show();
|
28 |
+
button.siblings('.loader').addClass('hidden');
|
29 |
+
},
|
30 |
+
listen_status: function () {
|
31 |
+
this.interval = setInterval(this.get_status.bind(this), 10000); //check status every 10 secs
|
32 |
+
},
|
33 |
+
get_status: function () {
|
34 |
+
var interval = this.interval;
|
35 |
+
jQuery.ajax( {
|
36 |
+
type: "GET",
|
37 |
+
url: this.ajax_url,
|
38 |
+
success: function( response ) {
|
39 |
+
if (response === 'OK') {
|
40 |
+
clearInterval(interval);
|
41 |
+
Printful_Connect.send_return_message();
|
42 |
+
}
|
43 |
+
}
|
44 |
+
});
|
45 |
+
},
|
46 |
+
listen_auth_return: function () {
|
47 |
+
var intercom = Intercom.getInstance();
|
48 |
+
intercom.on('printful-auth', function (data) {
|
49 |
+
if (data.success === true) {
|
50 |
+
location.reload();
|
51 |
+
}
|
52 |
+
});
|
53 |
+
},
|
54 |
+
send_return_message: function () {
|
55 |
+
var intercom = Intercom.getInstance();
|
56 |
+
intercom.emit('printful-auth', {success: true});
|
57 |
+
window.top.close();
|
58 |
+
}
|
59 |
+
};
|
60 |
})();
|
assets/js/intercom.min.js
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
-
/*! intercom.js | https://github.com/diy/intercom.js | Apache License (v2) */
|
2 |
-
var Intercom=function(){var g=function(){};g.createInterface=function(b){return{on:function(a,c){"undefined"===typeof this[b]&&(this[b]={});this[b].hasOwnProperty(a)||(this[b][a]=[]);this[b][a].push(c)},off:function(a,c){"undefined"!==typeof this[b]&&this[b].hasOwnProperty(a)&&i.removeItem(c,this[b][a])},trigger:function(a){if("undefined"!==typeof this[b]&&this[b].hasOwnProperty(a))for(var c=Array.prototype.slice.call(arguments,1),e=0;e<this[b][a].length;e++)this[b][a][e].apply(this[b][a][e],c)}}};
|
3 |
-
var m=g.createInterface("_handlers");g.prototype._on=m.on;g.prototype._off=m.off;g.prototype._trigger=m.trigger;var n=g.createInterface("handlers");g.prototype.on=function(){n.on.apply(this,arguments);Array.prototype.unshift.call(arguments,"on");this._trigger.apply(this,arguments)};g.prototype.off=n.off;g.prototype.trigger=n.trigger;var f=window.localStorage;"undefined"===typeof f&&(f={getItem:function(){},setItem:function(){},removeItem:function(){}});var i={},h=function(){return(65536*(1+Math.random())|
|
4 |
-
0).toString(16).substring(1)};i.guid=function(){return h()+h()+"-"+h()+"-"+h()+"-"+h()+"-"+h()+h()+h()};i.throttle=function(b,a){var c=0;return function(){var e=(new Date).getTime();e-c>b&&(c=e,a.apply(this,arguments))}};i.extend=function(b,a){if("undefined"===typeof b||!b)b={};if("object"===typeof a)for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b};i.removeItem=function(b,a){for(var c=a.length-1;0<=c;c--)a[c]===b&&a.splice(c,1);return a};var d=function(){var b=this,a=(new Date).getTime();
|
5 |
-
this.origin=i.guid();this.lastMessage=a;this.bindings=[];this.receivedIDs={};this.previousValues={};a=function(){b._onStorageEvent.apply(b,arguments)};window.attachEvent?document.attachEvent("onstorage",a):window.addEventListener("storage",a,!1)};d.prototype._transaction=function(b){var a=this,c=!1,e=!1,p=null,d=function(){if(!c){var g=(new Date).getTime(),s=parseInt(f.getItem(l)||0);s&&1E3>g-s?(e||(a._on("storage",d),e=!0),p=window.setTimeout(d,20)):(c=!0,f.setItem(l,g),b(),e&&a._off("storage",d),
|
6 |
-
p&&window.clearTimeout(p),f.removeItem(l))}};d()};d.prototype._cleanup_emit=i.throttle(100,function(){this._transaction(function(){for(var b=(new Date).getTime()-t,a=0,c=JSON.parse(f.getItem(j)||"[]"),e=c.length-1;0<=e;e--)c[e].timestamp<b&&(c.splice(e,1),a++);0<a&&f.setItem(j,JSON.stringify(c))})});d.prototype._cleanup_once=i.throttle(100,function(){var b=this;this._transaction(function(){var a,c=JSON.parse(f.getItem(k)||"{}");(new Date).getTime();var e=0;for(a in c)b._once_expired(a,c)&&(delete c[a],
|
7 |
-
e++);0<e&&f.setItem(k,JSON.stringify(c))})});d.prototype._once_expired=function(b,a){if(!a||!a.hasOwnProperty(b)||"object"!==typeof a[b])return!0;var c=a[b].ttl||u,e=(new Date).getTime();return a[b].timestamp<e-c};d.prototype._localStorageChanged=function(b,a){if(b&&b.key)return b.key===a;var c=f.getItem(a);if(c===this.previousValues[a])return!1;this.previousValues[a]=c;return!0};d.prototype._onStorageEvent=function(b){var b=b||window.event,a=this;this._localStorageChanged(b,j)&&this._transaction(function(){for(var b=
|
8 |
-
(new Date).getTime(),e=f.getItem(j),e=JSON.parse(e||"[]"),d=0;d<e.length;d++)if(e[d].origin!==a.origin&&!(e[d].timestamp<a.lastMessage)){if(e[d].id){if(a.receivedIDs.hasOwnProperty(e[d].id))continue;a.receivedIDs[e[d].id]=!0}a.trigger(e[d].name,e[d].payload)}a.lastMessage=b});this._trigger("storage",b)};d.prototype._emit=function(b,a,c){if((c="string"===typeof c||"number"===typeof c?String(c):null)&&c.length){if(this.receivedIDs.hasOwnProperty(c))return;this.receivedIDs[c]=!0}var e={id:c,name:b,origin:this.origin,
|
9 |
-
timestamp:(new Date).getTime(),payload:a},d=this;this._transaction(function(){var c=f.getItem(j)||"[]",c=[c.substring(0,c.length-1),"[]"===c?"":",",JSON.stringify(e),"]"].join("");f.setItem(j,c);d.trigger(b,a);window.setTimeout(function(){d._cleanup_emit()},50)})};d.prototype.bind=function(b,a){for(var c=0;c<d.bindings.length;c++){var e=d.bindings[c].factory(b,a||null,this);e&&this.bindings.push(e)}};d.prototype.emit=function(b,a){this._emit.apply(this,arguments);this._trigger("emit",b,a)};d.prototype.once=
|
10 |
-
function(b,a,c){if(d.supported){var e=this;this._transaction(function(){var d=JSON.parse(f.getItem(k)||"{}");e._once_expired(b,d)&&(d[b]={},d[b].timestamp=(new Date).getTime(),"number"===typeof c&&(d[b].ttl=1E3*c),f.setItem(k,JSON.stringify(d)),a(),window.setTimeout(function(){e._cleanup_once()},50))})}};i.extend(d.prototype,g.prototype);d.bindings=[];d.supported="undefined"!==typeof f;var j="intercom",k="intercom_once",l="intercom_lock",t=5E4,u=36E5;d.destroy=function(){f.removeItem(l);f.removeItem(j);
|
11 |
-
f.removeItem(k)};var q=null;d.getInstance=function(){q||(q=new d);return q};var r=function(b,a,c){a=i.extend({id:null,send:!0,receive:!0},a);if(a.receive){var d=[],f=function(f){-1===d.indexOf(f)&&(d.push(f),b.on(f,function(b){var d="function"===typeof a.id?a.id(f,b):null,e="function"===typeof a.receive?a.receive(f,b):!0;(e||"boolean"!==typeof e)&&c._emit(f,b,d)}))},g;for(g in c.handlers)for(var h=0;h<c.handlers[g].length;h++)f(g,c.handlers[g][h]);c._on("on",f)}a.send&&c._on("emit",function(c,d){var e=
|
12 |
"function"===typeof a.send?a.send(c,d):!0;(e||"boolean"!==typeof e)&&b.emit(c,d)})};r.factory=function(b,a,c){return"undefined"===typeof b.socket?!1:new r(b,a,c)};d.bindings.push(r);return d}();
|
1 |
+
/*! intercom.js | https://github.com/diy/intercom.js | Apache License (v2) */
|
2 |
+
var Intercom=function(){var g=function(){};g.createInterface=function(b){return{on:function(a,c){"undefined"===typeof this[b]&&(this[b]={});this[b].hasOwnProperty(a)||(this[b][a]=[]);this[b][a].push(c)},off:function(a,c){"undefined"!==typeof this[b]&&this[b].hasOwnProperty(a)&&i.removeItem(c,this[b][a])},trigger:function(a){if("undefined"!==typeof this[b]&&this[b].hasOwnProperty(a))for(var c=Array.prototype.slice.call(arguments,1),e=0;e<this[b][a].length;e++)this[b][a][e].apply(this[b][a][e],c)}}};
|
3 |
+
var m=g.createInterface("_handlers");g.prototype._on=m.on;g.prototype._off=m.off;g.prototype._trigger=m.trigger;var n=g.createInterface("handlers");g.prototype.on=function(){n.on.apply(this,arguments);Array.prototype.unshift.call(arguments,"on");this._trigger.apply(this,arguments)};g.prototype.off=n.off;g.prototype.trigger=n.trigger;var f=window.localStorage;"undefined"===typeof f&&(f={getItem:function(){},setItem:function(){},removeItem:function(){}});var i={},h=function(){return(65536*(1+Math.random())|
|
4 |
+
0).toString(16).substring(1)};i.guid=function(){return h()+h()+"-"+h()+"-"+h()+"-"+h()+"-"+h()+h()+h()};i.throttle=function(b,a){var c=0;return function(){var e=(new Date).getTime();e-c>b&&(c=e,a.apply(this,arguments))}};i.extend=function(b,a){if("undefined"===typeof b||!b)b={};if("object"===typeof a)for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b};i.removeItem=function(b,a){for(var c=a.length-1;0<=c;c--)a[c]===b&&a.splice(c,1);return a};var d=function(){var b=this,a=(new Date).getTime();
|
5 |
+
this.origin=i.guid();this.lastMessage=a;this.bindings=[];this.receivedIDs={};this.previousValues={};a=function(){b._onStorageEvent.apply(b,arguments)};window.attachEvent?document.attachEvent("onstorage",a):window.addEventListener("storage",a,!1)};d.prototype._transaction=function(b){var a=this,c=!1,e=!1,p=null,d=function(){if(!c){var g=(new Date).getTime(),s=parseInt(f.getItem(l)||0);s&&1E3>g-s?(e||(a._on("storage",d),e=!0),p=window.setTimeout(d,20)):(c=!0,f.setItem(l,g),b(),e&&a._off("storage",d),
|
6 |
+
p&&window.clearTimeout(p),f.removeItem(l))}};d()};d.prototype._cleanup_emit=i.throttle(100,function(){this._transaction(function(){for(var b=(new Date).getTime()-t,a=0,c=JSON.parse(f.getItem(j)||"[]"),e=c.length-1;0<=e;e--)c[e].timestamp<b&&(c.splice(e,1),a++);0<a&&f.setItem(j,JSON.stringify(c))})});d.prototype._cleanup_once=i.throttle(100,function(){var b=this;this._transaction(function(){var a,c=JSON.parse(f.getItem(k)||"{}");(new Date).getTime();var e=0;for(a in c)b._once_expired(a,c)&&(delete c[a],
|
7 |
+
e++);0<e&&f.setItem(k,JSON.stringify(c))})});d.prototype._once_expired=function(b,a){if(!a||!a.hasOwnProperty(b)||"object"!==typeof a[b])return!0;var c=a[b].ttl||u,e=(new Date).getTime();return a[b].timestamp<e-c};d.prototype._localStorageChanged=function(b,a){if(b&&b.key)return b.key===a;var c=f.getItem(a);if(c===this.previousValues[a])return!1;this.previousValues[a]=c;return!0};d.prototype._onStorageEvent=function(b){var b=b||window.event,a=this;this._localStorageChanged(b,j)&&this._transaction(function(){for(var b=
|
8 |
+
(new Date).getTime(),e=f.getItem(j),e=JSON.parse(e||"[]"),d=0;d<e.length;d++)if(e[d].origin!==a.origin&&!(e[d].timestamp<a.lastMessage)){if(e[d].id){if(a.receivedIDs.hasOwnProperty(e[d].id))continue;a.receivedIDs[e[d].id]=!0}a.trigger(e[d].name,e[d].payload)}a.lastMessage=b});this._trigger("storage",b)};d.prototype._emit=function(b,a,c){if((c="string"===typeof c||"number"===typeof c?String(c):null)&&c.length){if(this.receivedIDs.hasOwnProperty(c))return;this.receivedIDs[c]=!0}var e={id:c,name:b,origin:this.origin,
|
9 |
+
timestamp:(new Date).getTime(),payload:a},d=this;this._transaction(function(){var c=f.getItem(j)||"[]",c=[c.substring(0,c.length-1),"[]"===c?"":",",JSON.stringify(e),"]"].join("");f.setItem(j,c);d.trigger(b,a);window.setTimeout(function(){d._cleanup_emit()},50)})};d.prototype.bind=function(b,a){for(var c=0;c<d.bindings.length;c++){var e=d.bindings[c].factory(b,a||null,this);e&&this.bindings.push(e)}};d.prototype.emit=function(b,a){this._emit.apply(this,arguments);this._trigger("emit",b,a)};d.prototype.once=
|
10 |
+
function(b,a,c){if(d.supported){var e=this;this._transaction(function(){var d=JSON.parse(f.getItem(k)||"{}");e._once_expired(b,d)&&(d[b]={},d[b].timestamp=(new Date).getTime(),"number"===typeof c&&(d[b].ttl=1E3*c),f.setItem(k,JSON.stringify(d)),a(),window.setTimeout(function(){e._cleanup_once()},50))})}};i.extend(d.prototype,g.prototype);d.bindings=[];d.supported="undefined"!==typeof f;var j="intercom",k="intercom_once",l="intercom_lock",t=5E4,u=36E5;d.destroy=function(){f.removeItem(l);f.removeItem(j);
|
11 |
+
f.removeItem(k)};var q=null;d.getInstance=function(){q||(q=new d);return q};var r=function(b,a,c){a=i.extend({id:null,send:!0,receive:!0},a);if(a.receive){var d=[],f=function(f){-1===d.indexOf(f)&&(d.push(f),b.on(f,function(b){var d="function"===typeof a.id?a.id(f,b):null,e="function"===typeof a.receive?a.receive(f,b):!0;(e||"boolean"!==typeof e)&&c._emit(f,b,d)}))},g;for(g in c.handlers)for(var h=0;h<c.handlers[g].length;h++)f(g,c.handlers[g][h]);c._on("on",f)}a.send&&c._on("emit",function(c,d){var e=
|
12 |
"function"===typeof a.send?a.send(c,d):!0;(e||"boolean"!==typeof e)&&b.emit(c,d)})};r.factory=function(b,a,c){return"undefined"===typeof b.socket?!1:new r(b,a,c)};d.bindings.push(r);return d}();
|
assets/js/product-size-guide.js
ADDED
@@ -0,0 +1,439 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** Define class */
|
2 |
+
var Printful_Product_Size_Guide;
|
3 |
+
|
4 |
+
(function () {
|
5 |
+
'use strict';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @type {{modal: null, onSizeGuideClick: onSizeGuideClick, closeModal: closeModal, createModal: (function(string): HTMLDivElement)}}
|
9 |
+
*/
|
10 |
+
Printful_Product_Size_Guide = {
|
11 |
+
modal: null,
|
12 |
+
modalContentNode: null,
|
13 |
+
modalBodyNode: null,
|
14 |
+
sizeChartNode: null,
|
15 |
+
/**
|
16 |
+
* @var {{}}
|
17 |
+
* @var {Array<string>} sizeGuideData.availableSizes
|
18 |
+
* @var {{}} sizeGuideData.modelMeasurements
|
19 |
+
* @var {{}} sizeGuideData.productMeasurements
|
20 |
+
*/
|
21 |
+
sizeGuideData: null,
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Handle click event
|
25 |
+
*/
|
26 |
+
onSizeGuideClick: function () {
|
27 |
+
if (!window.pfGlobal || !window.pfGlobal.sg_data_raw) {
|
28 |
+
return;
|
29 |
+
}
|
30 |
+
this.sizeGuideData = JSON.parse(window.pfGlobal.sg_data_raw);
|
31 |
+
document.body.appendChild(this.createModal());
|
32 |
+
},
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Close the modal element
|
36 |
+
*/
|
37 |
+
closeModal: function () {
|
38 |
+
this.removeNode(this.sizeChartNode);
|
39 |
+
this.removeNode(this.modalContentNode);
|
40 |
+
this.removeNode(this.modalBodyNode);
|
41 |
+
this.removeNode(this.modal);
|
42 |
+
this.sizeChartNode = null;
|
43 |
+
this.modalContentNode = null;
|
44 |
+
this.modalBodyNode = null;
|
45 |
+
this.modal = null;
|
46 |
+
},
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Create modal content
|
50 |
+
* @returns {HTMLDivElement}
|
51 |
+
*/
|
52 |
+
createModal: function () {
|
53 |
+
// Clear the old one just to be sure
|
54 |
+
this.closeModal();
|
55 |
+
this.modal = this.buildEl('div', 'pf-size-guide-modal-wrapper');
|
56 |
+
this.modalBodyNode = this.buildEl('div', 'pf-size-guide-modal');
|
57 |
+
this.modalBodyNode.style.color = this.getTextColor();
|
58 |
+
this.modalBodyNode.style.backgroundColor = this.getBackGroundColor();
|
59 |
+
this.modalBodyNode.appendChild(this.buildModalHeader());
|
60 |
+
|
61 |
+
// Render initial active tab
|
62 |
+
this.renderModalContent(Printful_Product_Size_Guide.TAB_TYPE_PERSON);
|
63 |
+
this.modal.appendChild(this.modalBodyNode);
|
64 |
+
|
65 |
+
return this.modal;
|
66 |
+
},
|
67 |
+
|
68 |
+
buildEl: function (tagName, className, attributes) {
|
69 |
+
attributes = attributes || {};
|
70 |
+
var el = document.createElement(tagName);
|
71 |
+
if (className) {
|
72 |
+
el.className = className;
|
73 |
+
}
|
74 |
+
|
75 |
+
if (attributes.id) {
|
76 |
+
el.setAttribute('id', attributes.id);
|
77 |
+
}
|
78 |
+
|
79 |
+
if (attributes.innerHTML) {
|
80 |
+
el.innerHTML = attributes.innerHTML;
|
81 |
+
}
|
82 |
+
|
83 |
+
if (attributes.src) {
|
84 |
+
el.setAttribute('src', attributes.src);
|
85 |
+
}
|
86 |
+
|
87 |
+
if (attributes.onclick) {
|
88 |
+
el.onclick = attributes.onclick;
|
89 |
+
}
|
90 |
+
|
91 |
+
if (['td', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].indexOf(tagName) > -1) {
|
92 |
+
el.style.backgroundColor = this.getBackGroundColor();
|
93 |
+
el.style.color = this.getTextColor();
|
94 |
+
}
|
95 |
+
|
96 |
+
return el;
|
97 |
+
},
|
98 |
+
|
99 |
+
removeNode: function (node) {
|
100 |
+
if (node && node.parentNode && node.parentNode.tagName) {
|
101 |
+
node.parentNode.removeChild(node);
|
102 |
+
}
|
103 |
+
},
|
104 |
+
|
105 |
+
renderModalContent: function (activeTabType) {
|
106 |
+
this.removeNode(this.modalContentNode);
|
107 |
+
this.modalContentNode = this.buildEl('div', 'pf-size-guide-modal__content');
|
108 |
+
|
109 |
+
var tabData = this.getSizeGuideDataForTab(activeTabType),
|
110 |
+
tabTitle = this.getTabTitle(activeTabType);
|
111 |
+
|
112 |
+
this.modalContentNode.appendChild(this.buildSizeGuideTabsNode(activeTabType));
|
113 |
+
this.modalContentNode.appendChild(this.buildTabContent(tabData, tabTitle));
|
114 |
+
|
115 |
+
this.modalBodyNode.appendChild(this.modalContentNode);
|
116 |
+
},
|
117 |
+
|
118 |
+
getSizeGuideDataForTab: function (tabType) {
|
119 |
+
if (tabType === Printful_Product_Size_Guide.TAB_TYPE_PERSON) {
|
120 |
+
return this.sizeGuideData.modelMeasurements;
|
121 |
+
}
|
122 |
+
|
123 |
+
if (tabType === Printful_Product_Size_Guide.TAB_TYPE_PRODUCT) {
|
124 |
+
return this.sizeGuideData.productMeasurements;
|
125 |
+
}
|
126 |
+
|
127 |
+
return {};
|
128 |
+
},
|
129 |
+
|
130 |
+
getTabTitle: function (tabType) {
|
131 |
+
if (tabType === Printful_Product_Size_Guide.TAB_TYPE_PERSON) {
|
132 |
+
return window.pfGlobal && window.pfGlobal.sg_tab_title_person ? window.pfGlobal.sg_tab_title_person : 'Measure yourself';
|
133 |
+
}
|
134 |
+
|
135 |
+
return window.pfGlobal && window.pfGlobal.sg_tab_title_product ? window.pfGlobal.sg_tab_title_product : 'Product measurements';
|
136 |
+
},
|
137 |
+
|
138 |
+
renderSizeChart: function (measurementData, selectedUnit) {
|
139 |
+
if (this.sizeChartNode) {
|
140 |
+
this.removeNode(this.sizeChartNode.firstChild);
|
141 |
+
} else {
|
142 |
+
this.sizeChartNode = this.buildEl('div', 'pf-size-guide-modal-size-chart');
|
143 |
+
}
|
144 |
+
|
145 |
+
this.sizeChartNode.appendChild(this.buildSizeChartBlock(measurementData, selectedUnit));
|
146 |
+
},
|
147 |
+
|
148 |
+
buildModalHeader: function () {
|
149 |
+
var title = window.pfGlobal && window.pfGlobal.sg_modal_title ? window.pfGlobal.sg_modal_title : 'Size guide',
|
150 |
+
wrapper = this.buildEl('div', 'pf-size-guide-modal__header');
|
151 |
+
|
152 |
+
wrapper.appendChild(this.buildEl('h4', 'pf-size-guide-modal__title', {innerHTML: title}));
|
153 |
+
|
154 |
+
var closeBtn = this.buildEl('button', 'pf-size-guide-modal__close'),
|
155 |
+
img = this.buildEl('img');
|
156 |
+
|
157 |
+
img.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=";
|
158 |
+
closeBtn.appendChild(img);
|
159 |
+
closeBtn.onclick = (this.closeModal).bind(this);
|
160 |
+
|
161 |
+
wrapper.appendChild(closeBtn);
|
162 |
+
wrapper.append(this.buildEl('div', 'pf-size-guide-modal-clear'));
|
163 |
+
|
164 |
+
return wrapper;
|
165 |
+
},
|
166 |
+
|
167 |
+
buildSizeGuideTabsNode: function (activeTabType) {
|
168 |
+
var tabs = this.buildEl('ul', 'pf-product-size-guide__tabs');
|
169 |
+
tabs.appendChild(this.buildSizeGuideTabNode(this.getTabTitle(Printful_Product_Size_Guide.TAB_TYPE_PERSON), Printful_Product_Size_Guide.TAB_TYPE_PERSON, activeTabType));
|
170 |
+
tabs.appendChild(this.buildSizeGuideTabNode(this.getTabTitle(Printful_Product_Size_Guide.TAB_TYPE_PRODUCT), Printful_Product_Size_Guide.TAB_TYPE_PRODUCT, activeTabType));
|
171 |
+
|
172 |
+
return tabs;
|
173 |
+
},
|
174 |
+
|
175 |
+
buildSizeGuideTabNode: function (title, type, activeType) {
|
176 |
+
var className = 'pf-product-size-guide__tab';
|
177 |
+
|
178 |
+
if (type === activeType) {
|
179 |
+
className += ' pf-product-size-guide__tab--active';
|
180 |
+
}
|
181 |
+
|
182 |
+
var tab = this.buildEl('li', className, {
|
183 |
+
innerHTML: title,
|
184 |
+
onclick: (this.renderModalContent).bind(this, type)
|
185 |
+
});
|
186 |
+
|
187 |
+
if (type === activeType) {
|
188 |
+
tab.style.backgroundColor = this.getTabBackGroundColor(true);
|
189 |
+
} else {
|
190 |
+
tab.style.backgroundColor = this.getTabBackGroundColor(false);
|
191 |
+
}
|
192 |
+
|
193 |
+
return tab;
|
194 |
+
},
|
195 |
+
|
196 |
+
buildTabContent: function (measurementData, title) {
|
197 |
+
measurementData = measurementData || {};
|
198 |
+
var node = this.buildEl('div');
|
199 |
+
node.appendChild(this.buildEl('h4', null, {innerHTML: title}));
|
200 |
+
if (measurementData.hasOwnProperty('description')) {
|
201 |
+
node.appendChild(this.buildEl('div', null, {innerHTML: measurementData.description}));
|
202 |
+
}
|
203 |
+
|
204 |
+
// Model description
|
205 |
+
node.appendChild(this.buildDescriptionBlock(measurementData));
|
206 |
+
|
207 |
+
// Size table
|
208 |
+
this.renderSizeChart(measurementData);
|
209 |
+
node.appendChild(this.sizeChartNode);
|
210 |
+
|
211 |
+
return node;
|
212 |
+
},
|
213 |
+
|
214 |
+
buildDescriptionBlock: function (measurementData) {
|
215 |
+
var node = this.buildEl('div', 'pf-size-guide-modal-measurements');
|
216 |
+
if (measurementData.hasOwnProperty('imageUrl') && measurementData.imageUrl) {
|
217 |
+
var measurementImgNode = this.buildEl('div', 'pf-size-guide-modal-measurements__image');
|
218 |
+
measurementImgNode.appendChild(this.buildEl('img', null, {src: measurementData.imageUrl}));
|
219 |
+
|
220 |
+
if (measurementData.hasOwnProperty('modelDescription')) {
|
221 |
+
measurementImgNode.appendChild(this.buildEl('div', null, {innerHTML: measurementData.modelDescription}));
|
222 |
+
}
|
223 |
+
node.appendChild(measurementImgNode);
|
224 |
+
}
|
225 |
+
|
226 |
+
if (measurementData.hasOwnProperty('imageDescription')) {
|
227 |
+
node.appendChild(this.buildEl('div', 'pf-size-guide-modal-measurements__description', {innerHTML: measurementData.imageDescription}));
|
228 |
+
}
|
229 |
+
node.append(this.buildEl('div', 'pf-size-guide-modal-clear'));
|
230 |
+
|
231 |
+
return node;
|
232 |
+
},
|
233 |
+
|
234 |
+
/**
|
235 |
+
* @param {{}} measurementData
|
236 |
+
* @param {string} [selectedUnit]
|
237 |
+
* @return {*}
|
238 |
+
*/
|
239 |
+
buildSizeChartBlock: function (measurementData, selectedUnit) {
|
240 |
+
var node = this.buildEl('div');
|
241 |
+
|
242 |
+
if (!measurementData.hasOwnProperty('sizeTableRows') || measurementData.sizeTableRows.length < 1) {
|
243 |
+
return node;
|
244 |
+
}
|
245 |
+
var sizeRows = measurementData.sizeTableRows,
|
246 |
+
availableUnits = this.getUniqueUnits(sizeRows);
|
247 |
+
|
248 |
+
// Selected or first if nothing selected
|
249 |
+
selectedUnit = selectedUnit || this.getDefaultUnit(availableUnits);
|
250 |
+
node.appendChild(this.buildSizeChartTabsNode(measurementData, availableUnits, selectedUnit));
|
251 |
+
node.appendChild(this.buildSizeChartTable(this.getSortedChartRows(sizeRows, selectedUnit)));
|
252 |
+
|
253 |
+
return node;
|
254 |
+
},
|
255 |
+
|
256 |
+
/**
|
257 |
+
* @param {{}} measurementData
|
258 |
+
* @param {Array<{key, title}>} availableUnits
|
259 |
+
* @param {string} selectedUnit
|
260 |
+
* @return {*}
|
261 |
+
*/
|
262 |
+
buildSizeChartTabsNode: function (measurementData, availableUnits, selectedUnit) {
|
263 |
+
availableUnits = availableUnits || [];
|
264 |
+
var tabsNode = this.buildEl('ul', 'pf-size-guide-modal-size-chart__tabs');
|
265 |
+
|
266 |
+
availableUnits.map((function (item) {
|
267 |
+
var className = 'pf-size-guide-modal-size-chart__tab';
|
268 |
+
if (item.key === selectedUnit) {
|
269 |
+
className += ' pf-size-guide-modal-size-chart__tab--active';
|
270 |
+
}
|
271 |
+
tabsNode.appendChild(this.buildEl('li', className, {
|
272 |
+
innerHTML: item.title,
|
273 |
+
onclick: (this.renderSizeChart).bind(this, measurementData, item.key)
|
274 |
+
}));
|
275 |
+
}).bind(this));
|
276 |
+
|
277 |
+
return tabsNode;
|
278 |
+
},
|
279 |
+
|
280 |
+
buildSizeChartTable: function (rows) {
|
281 |
+
var tableNode = this.buildEl('table', 'pf-size-guide-modal-size-chart__table'),
|
282 |
+
availableSizes = this.sizeGuideData.availableSizes;
|
283 |
+
|
284 |
+
var tableHeader = this.buildEl('thead'),
|
285 |
+
tableHeaderRow = this.buildEl('tr');
|
286 |
+
|
287 |
+
tableHeaderRow.appendChild(this.buildEl('td', null, {innerHTML: 'Size'}));
|
288 |
+
rows.map((function (row) {
|
289 |
+
tableHeaderRow.appendChild(this.buildEl('td', null, {innerHTML: row.title}));
|
290 |
+
}).bind(this));
|
291 |
+
|
292 |
+
tableHeader.appendChild(tableHeaderRow);
|
293 |
+
tableNode.appendChild(tableHeader);
|
294 |
+
|
295 |
+
// Loop all available sizes and print out a row for each type
|
296 |
+
var tableBody = this.buildEl('tbody');
|
297 |
+
availableSizes.map((function (size) {
|
298 |
+
var tableBodyRow = this.buildEl('tr');
|
299 |
+
tableBodyRow.appendChild(this.buildEl('td', null, {innerHTML: size}));
|
300 |
+
rows.map((function (row) {
|
301 |
+
tableBodyRow.appendChild(this.buildEl('td', null, {innerHTML: row.sizes[size] || ''}));
|
302 |
+
}).bind(this));
|
303 |
+
|
304 |
+
tableBody.appendChild(tableBodyRow);
|
305 |
+
}).bind(this));
|
306 |
+
|
307 |
+
tableNode.appendChild(tableBody);
|
308 |
+
|
309 |
+
return tableNode;
|
310 |
+
},
|
311 |
+
|
312 |
+
getSortedChartRows: function (sizeTableRows, selectedUnit) {
|
313 |
+
return sizeTableRows
|
314 |
+
.filter(function (row) {
|
315 |
+
return row.unit === selectedUnit;
|
316 |
+
}).map((function (row) {
|
317 |
+
var sizes = {};
|
318 |
+
for (var k in row.sizes) {
|
319 |
+
if (!row.sizes.hasOwnProperty(k)) {
|
320 |
+
continue;
|
321 |
+
}
|
322 |
+
|
323 |
+
// Convert to fractions if needed, round and join
|
324 |
+
sizes[k] = row.sizes[k].map((function (size) {
|
325 |
+
if (row.unit === Printful_Product_Size_Guide.UNIT_INCH) {
|
326 |
+
return this.convertToFraction(size);
|
327 |
+
} else {
|
328 |
+
return size.toFixed(1);
|
329 |
+
}
|
330 |
+
}).bind(this)).join(' - ');
|
331 |
+
}
|
332 |
+
|
333 |
+
return {
|
334 |
+
title: row.title,
|
335 |
+
sizes: sizes
|
336 |
+
};
|
337 |
+
}).bind(this));
|
338 |
+
},
|
339 |
+
|
340 |
+
convertToFraction: function (value) {
|
341 |
+
var split = String(value).split('.'),
|
342 |
+
integer = parseInt(split[0], 10);
|
343 |
+
|
344 |
+
if (!split[1]) {
|
345 |
+
return value;
|
346 |
+
}
|
347 |
+
|
348 |
+
var decimal = parseFloat('0.' + split[1]),
|
349 |
+
fraction = 0;
|
350 |
+
|
351 |
+
for (var fra in Printful_Product_Size_Guide.FRACTION_MAP) {
|
352 |
+
var compareValue = Printful_Product_Size_Guide.FRACTION_MAP[fra];
|
353 |
+
|
354 |
+
if (decimal < compareValue) {
|
355 |
+
fraction = fra;
|
356 |
+
break;
|
357 |
+
}
|
358 |
+
}
|
359 |
+
|
360 |
+
if (fraction === 0 && integer) {
|
361 |
+
integer++;
|
362 |
+
fraction = '';
|
363 |
+
}
|
364 |
+
|
365 |
+
return (integer > 0 ? integer + ' ' : '') + fraction;
|
366 |
+
},
|
367 |
+
|
368 |
+
/**
|
369 |
+
* @param {Array<{unit, unitName}>}sizeTableRows
|
370 |
+
* @return {Array<{key, title}>}
|
371 |
+
*/
|
372 |
+
getUniqueUnits: function (sizeTableRows) {
|
373 |
+
var uniqueUnits = {};
|
374 |
+
sizeTableRows.map(function (row) {
|
375 |
+
// Gather unique units
|
376 |
+
if (!uniqueUnits.hasOwnProperty(row.unit)) {
|
377 |
+
uniqueUnits[row.unit] = row.unitName;
|
378 |
+
}
|
379 |
+
});
|
380 |
+
|
381 |
+
var units = [];
|
382 |
+
for (var i in uniqueUnits) {
|
383 |
+
if (uniqueUnits.hasOwnProperty(i)) {
|
384 |
+
units.push({
|
385 |
+
key: i,
|
386 |
+
title: uniqueUnits[i]
|
387 |
+
});
|
388 |
+
}
|
389 |
+
}
|
390 |
+
|
391 |
+
return units;
|
392 |
+
},
|
393 |
+
|
394 |
+
getBackGroundColor: function () {
|
395 |
+
return window.pfGlobal && window.pfGlobal.sg_modal_background_color ? window.pfGlobal.sg_modal_background_color : '#FFF';
|
396 |
+
},
|
397 |
+
|
398 |
+
getTextColor: function () {
|
399 |
+
return window.pfGlobal && window.pfGlobal.sg_modal_text_color ? window.pfGlobal.sg_modal_text_color : '#000';
|
400 |
+
},
|
401 |
+
|
402 |
+
getTabBackGroundColor: function (isActive) {
|
403 |
+
if (isActive) {
|
404 |
+
return window.pfGlobal && window.pfGlobal.sg_active_tab_background_color ? window.pfGlobal.sg_active_tab_background_color : '#FFF';
|
405 |
+
}
|
406 |
+
|
407 |
+
return window.pfGlobal && window.pfGlobal.sg_tab_background_color ? window.pfGlobal.sg_tab_background_color : '#EEE';
|
408 |
+
},
|
409 |
+
|
410 |
+
getDefaultUnit: function (availableUnits) {
|
411 |
+
availableUnits = availableUnits || [];
|
412 |
+
var uniqueUnitTypes = availableUnits.map(function (item) {
|
413 |
+
return item.key;
|
414 |
+
});
|
415 |
+
|
416 |
+
var defaultUnit = uniqueUnitTypes[0];
|
417 |
+
if (window.pfGlobal && window.pfGlobal.sg_primary_unit && uniqueUnitTypes.indexOf(window.pfGlobal.sg_primary_unit) > -1) {
|
418 |
+
return window.pfGlobal.sg_primary_unit;
|
419 |
+
}
|
420 |
+
|
421 |
+
return defaultUnit;
|
422 |
+
}
|
423 |
+
};
|
424 |
+
|
425 |
+
Printful_Product_Size_Guide.TAB_TYPE_PERSON = 'person';
|
426 |
+
Printful_Product_Size_Guide.TAB_TYPE_PRODUCT = 'product';
|
427 |
+
Printful_Product_Size_Guide.UNIT_INCH = 'inch';
|
428 |
+
|
429 |
+
Printful_Product_Size_Guide.FRACTION_MAP = {
|
430 |
+
' ': 0.0625, //don't add any fraction
|
431 |
+
'⅛': 0.187,
|
432 |
+
'¼': 0.3125,
|
433 |
+
'⅜': 0.4375,
|
434 |
+
'½': 0.5625,
|
435 |
+
'⅝': 0.6875,
|
436 |
+
'¾': 0.8125,
|
437 |
+
'⅞': 0.9375
|
438 |
+
};
|
439 |
+
})();
|
assets/js/settings.js
CHANGED
@@ -1,44 +1,44 @@
|
|
1 |
-
var Printful_Settings;
|
2 |
-
|
3 |
-
(function () {
|
4 |
-
'use strict';
|
5 |
-
|
6 |
-
Printful_Settings = {
|
7 |
-
init_submit: function () {
|
8 |
-
|
9 |
-
var form = jQuery('form[name=printful_settings]');
|
10 |
-
var submit_button = form.find('.woocommerce-save-button');
|
11 |
-
var loader = form.find('.loader');
|
12 |
-
var pass = form.find('.loader-wrap .pass');
|
13 |
-
var fail = form.find('.loader-wrap .fail');
|
14 |
-
|
15 |
-
submit_button.click(function (e) {
|
16 |
-
|
17 |
-
e.preventDefault();
|
18 |
-
submit_button.attr('disabled', 'disabled');
|
19 |
-
loader.show();
|
20 |
-
|
21 |
-
jQuery.ajax({
|
22 |
-
type: "POST",
|
23 |
-
url: form.attr('action'),
|
24 |
-
data: form.serialize(),
|
25 |
-
success: function (response) {
|
26 |
-
submit_button.removeAttr('disabled');
|
27 |
-
loader.hide();
|
28 |
-
|
29 |
-
if (response === 'OK') {
|
30 |
-
pass.show(0).delay(3000).hide(0);
|
31 |
-
} else {
|
32 |
-
fail.empty();
|
33 |
-
fail.append('<span class="dashicons dashicons-no"></span>' + response);
|
34 |
-
fail.show(0).delay(3000).hide(0);
|
35 |
-
}
|
36 |
-
}
|
37 |
-
});
|
38 |
-
});
|
39 |
-
},
|
40 |
-
enable_submit_btn: function () {
|
41 |
-
jQuery('.printful-submit input[type=submit]').removeClass('disabled').prop('disabled', false);
|
42 |
-
}
|
43 |
-
};
|
44 |
})();
|
1 |
+
var Printful_Settings;
|
2 |
+
|
3 |
+
(function () {
|
4 |
+
'use strict';
|
5 |
+
|
6 |
+
Printful_Settings = {
|
7 |
+
init_submit: function () {
|
8 |
+
|
9 |
+
var form = jQuery('form[name=printful_settings]');
|
10 |
+
var submit_button = form.find('.woocommerce-save-button');
|
11 |
+
var loader = form.find('.loader');
|
12 |
+
var pass = form.find('.loader-wrap .pass');
|
13 |
+
var fail = form.find('.loader-wrap .fail');
|
14 |
+
|
15 |
+
submit_button.click(function (e) {
|
16 |
+
|
17 |
+
e.preventDefault();
|
18 |
+
submit_button.attr('disabled', 'disabled');
|
19 |
+
loader.show();
|
20 |
+
|
21 |
+
jQuery.ajax({
|
22 |
+
type: "POST",
|
23 |
+
url: form.attr('action'),
|
24 |
+
data: form.serialize(),
|
25 |
+
success: function (response) {
|
26 |
+
submit_button.removeAttr('disabled');
|
27 |
+
loader.hide();
|
28 |
+
|
29 |
+
if (response === 'OK') {
|
30 |
+
pass.show(0).delay(3000).hide(0);
|
31 |
+
} else {
|
32 |
+
fail.empty();
|
33 |
+
fail.append('<span class="dashicons dashicons-no"></span>' + response);
|
34 |
+
fail.show(0).delay(3000).hide(0);
|
35 |
+
}
|
36 |
+
}
|
37 |
+
});
|
38 |
+
});
|
39 |
+
},
|
40 |
+
enable_submit_btn: function () {
|
41 |
+
jQuery('.printful-submit input[type=submit]').removeClass('disabled').prop('disabled', false);
|
42 |
+
}
|
43 |
+
};
|
44 |
})();
|
i18n/languages/printful.pot
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
msgid ""
|
3 |
msgstr ""
|
4 |
"Project-Id-Version: \n"
|
5 |
-
"POT-Creation-Date: 2020-
|
6 |
"PO-Revision-Date: 2018-04-26 13:50+0300\n"
|
7 |
"Last-Translator: \n"
|
8 |
"Language-Team: \n"
|
@@ -25,23 +25,23 @@ msgstr ""
|
|
25 |
msgid "Loading your orders..."
|
26 |
msgstr ""
|
27 |
|
28 |
-
#: includes/class-printful-admin-settings.php:
|
29 |
msgid "states where Printful applies sales tax"
|
30 |
msgstr ""
|
31 |
|
32 |
-
#: includes/class-printful-admin-settings.php:
|
33 |
msgid "Printful store API key"
|
34 |
msgstr ""
|
35 |
|
36 |
-
#: includes/class-printful-admin-settings.php:
|
37 |
msgid "Your store's Printful API key. Create it in the Prinful dashboard"
|
38 |
msgstr ""
|
39 |
|
40 |
-
#: includes/class-printful-admin-settings.php:
|
41 |
msgid "Calculate sales tax"
|
42 |
msgstr ""
|
43 |
|
44 |
-
#: includes/class-printful-admin-settings.php:
|
45 |
#, php-format
|
46 |
msgid ""
|
47 |
"Calculated for all products listed on your store (including non-Printful "
|
@@ -49,42 +49,114 @@ msgid ""
|
|
49 |
"a seller permit in all these states."
|
50 |
msgstr ""
|
51 |
|
52 |
-
#: includes/class-printful-admin-settings.php:
|
53 |
msgid "Disable SSL"
|
54 |
msgstr ""
|
55 |
|
56 |
-
#: includes/class-printful-admin-settings.php:
|
57 |
msgid ""
|
58 |
"Use HTTP instead of HTTPS to connect to the Printful API (may be required if "
|
59 |
"the plugin does not work for some hosting configurations)"
|
60 |
msgstr ""
|
61 |
|
62 |
-
#: includes/class-printful-admin-settings.php:
|
63 |
-
#: includes/class-printful-admin-settings.php:
|
64 |
msgid "Personalization button text"
|
65 |
msgstr ""
|
66 |
|
67 |
-
#: includes/class-printful-admin-settings.php:
|
68 |
msgid "Personalization button color"
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: includes/class-printful-admin-settings.php:
|
72 |
msgid "Personalization button background color"
|
73 |
msgstr ""
|
74 |
|
75 |
-
#: includes/class-printful-admin-settings.php:
|
76 |
msgid "Personalization popup title"
|
77 |
msgstr ""
|
78 |
|
79 |
-
#: includes/class-printful-admin-settings.php:
|
80 |
msgid "Personalization popup title text"
|
81 |
msgstr ""
|
82 |
|
83 |
-
#: includes/class-printful-admin-settings.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
msgid "Shipping Methods"
|
85 |
msgstr ""
|
86 |
|
87 |
-
#: includes/class-printful-admin-settings.php:
|
88 |
msgid ""
|
89 |
"Here you can choose the shipping methods you want Printful to use for "
|
90 |
"shipping your orders.\n"
|
@@ -93,15 +165,15 @@ msgid ""
|
|
93 |
"method for each order."
|
94 |
msgstr ""
|
95 |
|
96 |
-
#: includes/class-printful-admin-settings.php:
|
97 |
msgid "You need to be connected to Printful API to edit carrier settings!"
|
98 |
msgstr ""
|
99 |
|
100 |
-
#: includes/class-printful-admin-settings.php:
|
101 |
msgid "International from USA"
|
102 |
msgstr ""
|
103 |
|
104 |
-
#: includes/class-printful-admin-settings.php:
|
105 |
msgid "International from EU"
|
106 |
msgstr ""
|
107 |
|
@@ -316,6 +388,7 @@ msgid "Store Identifier"
|
|
316 |
msgstr ""
|
317 |
|
318 |
#: includes/class-printful-rest-api-controller.php:55
|
|
|
319 |
msgid "Unique identifier for the resource."
|
320 |
msgstr ""
|
321 |
|
@@ -323,27 +396,31 @@ msgstr ""
|
|
323 |
msgid "Printful size guide"
|
324 |
msgstr ""
|
325 |
|
326 |
-
#: includes/class-printful-rest-api-controller.php:
|
|
|
|
|
|
|
|
|
327 |
msgid "No size chart was provided"
|
328 |
msgstr ""
|
329 |
|
330 |
-
#: includes/class-printful-rest-api-controller.php:
|
331 |
msgid "The product ID is invalid"
|
332 |
msgstr ""
|
333 |
|
334 |
-
#: includes/class-printful-rest-api-controller.php:
|
335 |
msgid "The product is not found"
|
336 |
msgstr ""
|
337 |
|
338 |
-
#: includes/class-printful-rest-api-controller.php:
|
339 |
msgid "You do not have permission to edit the size chart"
|
340 |
msgstr ""
|
341 |
|
342 |
-
#: includes/class-printful-rest-api-controller.php:
|
343 |
msgid "Sorry, you cannot list resources."
|
344 |
msgstr ""
|
345 |
|
346 |
-
#: includes/class-printful-rest-api-controller.php:
|
347 |
msgid "Sorry, you are not allowed to edit this resource."
|
348 |
msgstr ""
|
349 |
|
@@ -371,15 +448,23 @@ msgstr ""
|
|
371 |
msgid "Display Printful status messages if rate API request fails"
|
372 |
msgstr ""
|
373 |
|
374 |
-
#: includes/class-printful-size-chart-tab.php:
|
375 |
msgid "Size chart"
|
376 |
msgstr ""
|
377 |
|
378 |
-
#: includes/class-printful-size-chart-tab.php:
|
379 |
-
#: includes/class-printful-size-chart-tab.php:
|
380 |
msgid "Size Chart"
|
381 |
msgstr ""
|
382 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
#: includes/class-printful-taxes.php:160
|
384 |
msgid "Sales Tax"
|
385 |
msgstr ""
|
2 |
msgid ""
|
3 |
msgstr ""
|
4 |
"Project-Id-Version: \n"
|
5 |
+
"POT-Creation-Date: 2020-08-17 14:22+0300\n"
|
6 |
"PO-Revision-Date: 2018-04-26 13:50+0300\n"
|
7 |
"Last-Translator: \n"
|
8 |
"Language-Team: \n"
|
25 |
msgid "Loading your orders..."
|
26 |
msgstr ""
|
27 |
|
28 |
+
#: includes/class-printful-admin-settings.php:35
|
29 |
msgid "states where Printful applies sales tax"
|
30 |
msgstr ""
|
31 |
|
32 |
+
#: includes/class-printful-admin-settings.php:40
|
33 |
msgid "Printful store API key"
|
34 |
msgstr ""
|
35 |
|
36 |
+
#: includes/class-printful-admin-settings.php:43
|
37 |
msgid "Your store's Printful API key. Create it in the Prinful dashboard"
|
38 |
msgstr ""
|
39 |
|
40 |
+
#: includes/class-printful-admin-settings.php:47
|
41 |
msgid "Calculate sales tax"
|
42 |
msgstr ""
|
43 |
|
44 |
+
#: includes/class-printful-admin-settings.php:50
|
45 |
#, php-format
|
46 |
msgid ""
|
47 |
"Calculated for all products listed on your store (including non-Printful "
|
49 |
"a seller permit in all these states."
|
50 |
msgstr ""
|
51 |
|
52 |
+
#: includes/class-printful-admin-settings.php:56
|
53 |
msgid "Disable SSL"
|
54 |
msgstr ""
|
55 |
|
56 |
+
#: includes/class-printful-admin-settings.php:58
|
57 |
msgid ""
|
58 |
"Use HTTP instead of HTTPS to connect to the Printful API (may be required if "
|
59 |
"the plugin does not work for some hosting configurations)"
|
60 |
msgstr ""
|
61 |
|
62 |
+
#: includes/class-printful-admin-settings.php:68
|
63 |
+
#: includes/class-printful-admin-settings.php:70
|
64 |
msgid "Personalization button text"
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: includes/class-printful-admin-settings.php:74
|
68 |
msgid "Personalization button color"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: includes/class-printful-admin-settings.php:76
|
72 |
msgid "Personalization button background color"
|
73 |
msgstr ""
|
74 |
|
75 |
+
#: includes/class-printful-admin-settings.php:80
|
76 |
msgid "Personalization popup title"
|
77 |
msgstr ""
|
78 |
|
79 |
+
#: includes/class-printful-admin-settings.php:82
|
80 |
msgid "Personalization popup title text"
|
81 |
msgstr ""
|
82 |
|
83 |
+
#: includes/class-printful-admin-settings.php:92
|
84 |
+
msgid "Size guide popup title"
|
85 |
+
msgstr ""
|
86 |
+
|
87 |
+
#: includes/class-printful-admin-settings.php:94
|
88 |
+
msgid "Size guide popup title text"
|
89 |
+
msgstr ""
|
90 |
+
|
91 |
+
#: includes/class-printful-admin-settings.php:98
|
92 |
+
#: includes/class-printful-admin-settings.php:100
|
93 |
+
msgid "Size guide popup text color"
|
94 |
+
msgstr ""
|
95 |
+
|
96 |
+
#: includes/class-printful-admin-settings.php:104
|
97 |
+
#: includes/class-printful-admin-settings.php:106
|
98 |
+
msgid "Size guide popup background color"
|
99 |
+
msgstr ""
|
100 |
+
|
101 |
+
#: includes/class-printful-admin-settings.php:110
|
102 |
+
#: includes/class-printful-admin-settings.php:112
|
103 |
+
msgid "Size guide tab background color"
|
104 |
+
msgstr ""
|
105 |
+
|
106 |
+
#: includes/class-printful-admin-settings.php:116
|
107 |
+
#: includes/class-printful-admin-settings.php:118
|
108 |
+
msgid "Size guide active tab background color"
|
109 |
+
msgstr ""
|
110 |
+
|
111 |
+
#: includes/class-printful-admin-settings.php:122
|
112 |
+
#: includes/class-printful-admin-settings.php:124
|
113 |
+
msgid "Size guide button text"
|
114 |
+
msgstr ""
|
115 |
+
|
116 |
+
#: includes/class-printful-admin-settings.php:128
|
117 |
+
#: includes/class-printful-admin-settings.php:130
|
118 |
+
msgid "Size guide button text color"
|
119 |
+
msgstr ""
|
120 |
+
|
121 |
+
#: includes/class-printful-admin-settings.php:134
|
122 |
+
msgid "Primary measurement unit"
|
123 |
+
msgstr ""
|
124 |
+
|
125 |
+
#: includes/class-printful-admin-settings.php:136
|
126 |
+
msgid "Primary measurement unit (cm/inch)"
|
127 |
+
msgstr ""
|
128 |
+
|
129 |
+
#: includes/class-printful-admin-settings.php:140
|
130 |
+
msgid "Inches"
|
131 |
+
msgstr ""
|
132 |
+
|
133 |
+
#: includes/class-printful-admin-settings.php:141
|
134 |
+
msgid "Centimeters"
|
135 |
+
msgstr ""
|
136 |
+
|
137 |
+
#: includes/class-printful-admin-settings.php:185
|
138 |
+
msgid "Integration settings"
|
139 |
+
msgstr ""
|
140 |
+
|
141 |
+
#: includes/class-printful-admin-settings.php:189
|
142 |
+
msgid "Product personalization settings"
|
143 |
+
msgstr ""
|
144 |
+
|
145 |
+
#: includes/class-printful-admin-settings.php:194
|
146 |
+
msgid "Size guide settings"
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: includes/class-printful-admin-settings.php:195
|
150 |
+
msgid ""
|
151 |
+
"These settings control how the new size guide will look on your WooCommerce "
|
152 |
+
"storefront. Products with an old size guide will not be affected."
|
153 |
+
msgstr ""
|
154 |
+
|
155 |
+
#: includes/class-printful-admin-settings.php:256
|
156 |
msgid "Shipping Methods"
|
157 |
msgstr ""
|
158 |
|
159 |
+
#: includes/class-printful-admin-settings.php:257
|
160 |
msgid ""
|
161 |
"Here you can choose the shipping methods you want Printful to use for "
|
162 |
"shipping your orders.\n"
|
165 |
"method for each order."
|
166 |
msgstr ""
|
167 |
|
168 |
+
#: includes/class-printful-admin-settings.php:263
|
169 |
msgid "You need to be connected to Printful API to edit carrier settings!"
|
170 |
msgstr ""
|
171 |
|
172 |
+
#: includes/class-printful-admin-settings.php:404
|
173 |
msgid "International from USA"
|
174 |
msgstr ""
|
175 |
|
176 |
+
#: includes/class-printful-admin-settings.php:410
|
177 |
msgid "International from EU"
|
178 |
msgstr ""
|
179 |
|
388 |
msgstr ""
|
389 |
|
390 |
#: includes/class-printful-rest-api-controller.php:55
|
391 |
+
#: includes/class-printful-rest-api-controller.php:75
|
392 |
msgid "Unique identifier for the resource."
|
393 |
msgstr ""
|
394 |
|
396 |
msgid "Printful size guide"
|
397 |
msgstr ""
|
398 |
|
399 |
+
#: includes/class-printful-rest-api-controller.php:81
|
400 |
+
msgid "Advanced Printful size guide"
|
401 |
+
msgstr ""
|
402 |
+
|
403 |
+
#: includes/class-printful-rest-api-controller.php:142
|
404 |
msgid "No size chart was provided"
|
405 |
msgstr ""
|
406 |
|
407 |
+
#: includes/class-printful-rest-api-controller.php:148
|
408 |
msgid "The product ID is invalid"
|
409 |
msgstr ""
|
410 |
|
411 |
+
#: includes/class-printful-rest-api-controller.php:155
|
412 |
msgid "The product is not found"
|
413 |
msgstr ""
|
414 |
|
415 |
+
#: includes/class-printful-rest-api-controller.php:161
|
416 |
msgid "You do not have permission to edit the size chart"
|
417 |
msgstr ""
|
418 |
|
419 |
+
#: includes/class-printful-rest-api-controller.php:241
|
420 |
msgid "Sorry, you cannot list resources."
|
421 |
msgstr ""
|
422 |
|
423 |
+
#: includes/class-printful-rest-api-controller.php:258
|
424 |
msgid "Sorry, you are not allowed to edit this resource."
|
425 |
msgstr ""
|
426 |
|
448 |
msgid "Display Printful status messages if rate API request fails"
|
449 |
msgstr ""
|
450 |
|
451 |
+
#: includes/class-printful-size-chart-tab.php:32
|
452 |
msgid "Size chart"
|
453 |
msgstr ""
|
454 |
|
455 |
+
#: includes/class-printful-size-chart-tab.php:43
|
456 |
+
#: includes/class-printful-size-chart-tab.php:56
|
457 |
msgid "Size Chart"
|
458 |
msgstr ""
|
459 |
|
460 |
+
#: includes/class-printful-size-guide.php:51
|
461 |
+
msgid "Measure yourself"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: includes/class-printful-size-guide.php:52
|
465 |
+
msgid "Product measurements"
|
466 |
+
msgstr ""
|
467 |
+
|
468 |
#: includes/class-printful-taxes.php:160
|
469 |
msgid "Sales Tax"
|
470 |
msgstr ""
|
includes/class-printful-admin-settings.php
CHANGED
@@ -14,6 +14,16 @@ class Printful_Admin_Settings {
|
|
14 |
const DEFAULT_PERSONALIZE_BUTTON_COLOR = '#eee';
|
15 |
const DEFAULT_PERSONALIZE_MODAL_TITLE = 'Create a personalized design';
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
/**
|
18 |
* @return array
|
19 |
*/
|
@@ -48,18 +58,24 @@ class Printful_Admin_Settings {
|
|
48 |
'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' ),
|
49 |
'default' => 'no',
|
50 |
),
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
'pfc_modal_title' => array(
|
64 |
'title' => __( 'Personalization popup title', 'printful' ),
|
65 |
'type' => 'text',
|
@@ -69,6 +85,72 @@ class Printful_Admin_Settings {
|
|
69 |
);
|
70 |
}
|
71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
/**
|
73 |
* @return Printful_Admin_Settings
|
74 |
*/
|
@@ -99,10 +181,22 @@ class Printful_Admin_Settings {
|
|
99 |
|
100 |
echo '<form method="post" name="printful_settings" action="' . esc_url( admin_url( 'admin-ajax.php?action=save_printful_settings' ) ) . '">';
|
101 |
|
102 |
-
//
|
103 |
-
$integration_settings = $this->
|
104 |
Printful_Admin::load_template( 'setting-group', $integration_settings );
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
Printful_Admin::load_template( 'shipping-notification' );
|
107 |
|
108 |
//carriers settings
|
@@ -129,25 +223,28 @@ class Printful_Admin_Settings {
|
|
129 |
exit;
|
130 |
}
|
131 |
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
|
|
|
|
|
|
143 |
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
|
150 |
-
|
151 |
}
|
152 |
|
153 |
/**
|
@@ -253,7 +350,7 @@ class Printful_Admin_Settings {
|
|
253 |
$options = array();
|
254 |
|
255 |
//build save options list
|
256 |
-
foreach ( self::
|
257 |
|
258 |
if ( $field['type'] == 'checkbox' ) {
|
259 |
if ( isset( $_POST[ $key ] ) ) {
|
14 |
const DEFAULT_PERSONALIZE_BUTTON_COLOR = '#eee';
|
15 |
const DEFAULT_PERSONALIZE_MODAL_TITLE = 'Create a personalized design';
|
16 |
|
17 |
+
// Size guide modal settings
|
18 |
+
const DEFAULT_SIZE_GUIDE_BUTTON_TEXT = 'Size Guide';
|
19 |
+
const DEFAULT_SIZE_GUIDE_BUTTON_COLOR = '#1164A9';
|
20 |
+
const DEFAULT_SIZE_GUIDE_MODAL_TITLE = 'Size guide';
|
21 |
+
const DEFAULT_SIZE_GUIDE_MODAL_TEXT_COLOR = '#000';
|
22 |
+
const DEFAULT_SIZE_GUIDE_MODAL_BACKGROUND_COLOR = '#fff';
|
23 |
+
const DEFAULT_SIZE_GUIDE_TAB_BACKGROUND_COLOR = '#fff';
|
24 |
+
const DEFAULT_SIZE_GUIDE_ACTIVE_TAB_BACKGROUND_COLOR = '#fff';
|
25 |
+
const DEFAULT_SIZE_GUIDE_UNIT = 'inch';
|
26 |
+
|
27 |
/**
|
28 |
* @return array
|
29 |
*/
|
58 |
'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' ),
|
59 |
'default' => 'no',
|
60 |
),
|
61 |
+
);
|
62 |
+
}
|
63 |
+
|
64 |
+
public static function getPersonalizationFields()
|
65 |
+
{
|
66 |
+
return array(
|
67 |
+
'pfc_button_text' => array(
|
68 |
+
'title' => __( 'Personalization button text', 'printful' ),
|
69 |
+
'type' => 'text',
|
70 |
+
'description' => __( 'Personalization button text', 'printful' ),
|
71 |
+
'default' => self::DEFAULT_PERSONALIZE_BUTTON_TEXT
|
72 |
+
),
|
73 |
+
'pfc_button_color' => array(
|
74 |
+
'title' => __( 'Personalization button color', 'printful' ),
|
75 |
+
'type' => 'color-picker',
|
76 |
+
'description' => __( 'Personalization button background color', 'printful' ),
|
77 |
+
'default' => self::DEFAULT_PERSONALIZE_BUTTON_COLOR,
|
78 |
+
),
|
79 |
'pfc_modal_title' => array(
|
80 |
'title' => __( 'Personalization popup title', 'printful' ),
|
81 |
'type' => 'text',
|
85 |
);
|
86 |
}
|
87 |
|
88 |
+
public static function getSizeGuideFields()
|
89 |
+
{
|
90 |
+
return array(
|
91 |
+
'pfsg_modal_title' => array(
|
92 |
+
'title' => __( 'Size guide popup title', 'printful' ),
|
93 |
+
'type' => 'text',
|
94 |
+
'description' => __( 'Size guide popup title text', 'printful' ),
|
95 |
+
'default' => self::DEFAULT_SIZE_GUIDE_MODAL_TITLE,
|
96 |
+
),
|
97 |
+
'pfsg_modal_text_color' => array(
|
98 |
+
'title' => __( 'Size guide popup text color', 'printful' ),
|
99 |
+
'type' => 'color-picker',
|
100 |
+
'description' => __( 'Size guide popup text color', 'printful' ),
|
101 |
+
'default' => self::DEFAULT_SIZE_GUIDE_MODAL_TEXT_COLOR,
|
102 |
+
),
|
103 |
+
'pfsg_modal_background_color' => array(
|
104 |
+
'title' => __( 'Size guide popup background color', 'printful' ),
|
105 |
+
'type' => 'color-picker',
|
106 |
+
'description' => __( 'Size guide popup background color', 'printful' ),
|
107 |
+
'default' => self::DEFAULT_SIZE_GUIDE_MODAL_BACKGROUND_COLOR,
|
108 |
+
),
|
109 |
+
'pfsg_tab_background_color' => array(
|
110 |
+
'title' => __( 'Size guide tab background color', 'printful' ),
|
111 |
+
'type' => 'color-picker',
|
112 |
+
'description' => __( 'Size guide tab background color', 'printful' ),
|
113 |
+
'default' => self::DEFAULT_SIZE_GUIDE_TAB_BACKGROUND_COLOR,
|
114 |
+
),
|
115 |
+
'pfsg_active_tab_background_color' => array(
|
116 |
+
'title' => __( 'Size guide active tab background color', 'printful' ),
|
117 |
+
'type' => 'color-picker',
|
118 |
+
'description' => __( 'Size guide active tab background color', 'printful' ),
|
119 |
+
'default' => self::DEFAULT_SIZE_GUIDE_ACTIVE_TAB_BACKGROUND_COLOR,
|
120 |
+
),
|
121 |
+
'pfsg_button_text' => array(
|
122 |
+
'title' => __( 'Size guide button text', 'printful' ),
|
123 |
+
'type' => 'text',
|
124 |
+
'description' => __( 'Size guide button text', 'printful' ),
|
125 |
+
'default' => self::DEFAULT_SIZE_GUIDE_BUTTON_TEXT,
|
126 |
+
),
|
127 |
+
'pfsg_button_color' => array(
|
128 |
+
'title' => __( 'Size guide button text color', 'printful' ),
|
129 |
+
'type' => 'color-picker',
|
130 |
+
'description' => __( 'Size guide button text color', 'printful' ),
|
131 |
+
'default' => self::DEFAULT_SIZE_GUIDE_BUTTON_COLOR,
|
132 |
+
),
|
133 |
+
'pfsg_primary_unit' => array(
|
134 |
+
'title' => __( 'Primary measurement unit', 'printful' ),
|
135 |
+
'type' => 'dropdown',
|
136 |
+
'description' => __( 'Primary measurement unit (cm/inch)', 'printful' ),
|
137 |
+
'default' => self::DEFAULT_SIZE_GUIDE_UNIT,
|
138 |
+
'selected' => Printful_Integration::instance()->get_option( 'pfsg_primary_unit' ),
|
139 |
+
'items' => [
|
140 |
+
'inch' => __('Inches', 'printful'),
|
141 |
+
'centimeter' => __('Centimeters', 'printful'),
|
142 |
+
],
|
143 |
+
),
|
144 |
+
);
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @return array
|
149 |
+
*/
|
150 |
+
public static function getAllFields() {
|
151 |
+
return array_merge(self::getIntegrationFields(), self::getPersonalizationFields(), self::getSizeGuideFields());
|
152 |
+
}
|
153 |
+
|
154 |
/**
|
155 |
* @return Printful_Admin_Settings
|
156 |
*/
|
181 |
|
182 |
echo '<form method="post" name="printful_settings" action="' . esc_url( admin_url( 'admin-ajax.php?action=save_printful_settings' ) ) . '">';
|
183 |
|
184 |
+
// Integration settings
|
185 |
+
$integration_settings = $this->setup_fields( __('Integration settings', 'printful'), '', self::getIntegrationFields() );
|
186 |
Printful_Admin::load_template( 'setting-group', $integration_settings );
|
187 |
|
188 |
+
// Product personalization settings
|
189 |
+
$personalization_settings = $this->setup_fields( __('Product personalization settings', 'printful'), '', self::getPersonalizationFields() );
|
190 |
+
Printful_Admin::load_template( 'setting-group', $personalization_settings );
|
191 |
+
|
192 |
+
// Size guide settings
|
193 |
+
$size_guide_settings = $this->setup_fields(
|
194 |
+
__('Size guide settings', 'printful'),
|
195 |
+
__('These settings control how the new size guide will look on your WooCommerce storefront. Products with an old size guide will not be affected.', 'printful'),
|
196 |
+
self::getSizeGuideFields()
|
197 |
+
);
|
198 |
+
Printful_Admin::load_template( 'setting-group', $size_guide_settings );
|
199 |
+
|
200 |
Printful_Admin::load_template( 'shipping-notification' );
|
201 |
|
202 |
//carriers settings
|
223 |
exit;
|
224 |
}
|
225 |
|
226 |
+
/**
|
227 |
+
* @param string $title Settings section title
|
228 |
+
* @param string $description Section description
|
229 |
+
* @param array $fields
|
230 |
+
*
|
231 |
+
* @return array
|
232 |
+
*/
|
233 |
+
public function setup_fields($title, $description = '', $fields = [])
|
234 |
+
{
|
235 |
+
$fieldGroup = array(
|
236 |
+
'title' => $title,
|
237 |
+
'description' => $description,
|
238 |
+
'settings' => $fields,
|
239 |
+
);
|
240 |
|
241 |
+
foreach ( $fieldGroup['settings'] as $key => $setting ) {
|
242 |
+
if ( $setting['type'] !== 'title' ) {
|
243 |
+
$fieldGroup['settings'][ $key ]['value'] = Printful_Integration::instance()->get_option( $key, $setting['default'] );
|
244 |
+
}
|
245 |
+
}
|
246 |
|
247 |
+
return $fieldGroup;
|
248 |
}
|
249 |
|
250 |
/**
|
350 |
$options = array();
|
351 |
|
352 |
//build save options list
|
353 |
+
foreach ( self::getAllFields() as $key => $field ) {
|
354 |
|
355 |
if ( $field['type'] == 'checkbox' ) {
|
356 |
if ( isset( $_POST[ $key ] ) ) {
|
includes/class-printful-admin.php
CHANGED
@@ -1,172 +1,172 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
-
|
4 |
-
class Printful_Admin {
|
5 |
-
|
6 |
-
const MENU_TITLE_TOP = 'Printful';
|
7 |
-
const PAGE_TITLE_DASHBOARD = 'Dashboard';
|
8 |
-
const MENU_TITLE_DASHBOARD = 'Dashboard';
|
9 |
-
const MENU_SLUG_DASHBOARD = 'printful-dashboard';
|
10 |
-
const CAPABILITY = 'manage_options';
|
11 |
-
|
12 |
-
public static function init() {
|
13 |
-
$admin = new self;
|
14 |
-
$admin->register_admin();
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Register admin scripts
|
19 |
-
*/
|
20 |
-
public function register_admin() {
|
21 |
-
|
22 |
-
add_action( 'admin_menu', array( $this, 'register_admin_menu_page' ) );
|
23 |
-
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_styles' ) );
|
24 |
-
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_scripts' ) );
|
25 |
-
add_action( 'wp_enqueue_scripts', array( $this, 'add_global_style' ) );
|
26 |
-
add_action( 'admin_bar_menu', array( $this, 'add_printful_status_toolbar' ), 999 );
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Loads stylesheets used in printful admin pages
|
31 |
-
* @param $hook
|
32 |
-
*/
|
33 |
-
public function add_admin_styles($hook) {
|
34 |
-
|
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__ ) );
|
42 |
-
wp_enqueue_style( 'printful-settings', plugins_url( '../assets/css/settings.css', __FILE__ ) );
|
43 |
-
}
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Loads stylesheet for printful toolbar element
|
48 |
-
*/
|
49 |
-
public function add_global_style() {
|
50 |
-
if ( is_user_logged_in() ) {
|
51 |
-
wp_enqueue_style( 'printful-global', plugins_url( '../assets/css/global.css', __FILE__ ) );
|
52 |
-
}
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Loads scripts used in printful admin pages
|
57 |
-
* @param $hook
|
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__ ) );
|
65 |
-
wp_enqueue_script( 'printful-intercom', plugins_url( '../assets/js/intercom.min.js', __FILE__ ) );
|
66 |
-
}
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Register admin menu pages
|
71 |
-
*/
|
72 |
-
public function register_admin_menu_page() {
|
73 |
-
|
74 |
-
add_menu_page(
|
75 |
-
__( 'Dashboard', 'printful' ),
|
76 |
-
self::MENU_TITLE_TOP,
|
77 |
-
self::CAPABILITY,
|
78 |
-
self::MENU_SLUG_DASHBOARD,
|
79 |
-
array( 'Printful_Admin', 'route' ),
|
80 |
-
Printful_Base::get_asset_url() . 'images/printful-menu-icon.png',
|
81 |
-
58
|
82 |
-
);
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Route the tabs
|
87 |
-
*/
|
88 |
-
public static function route() {
|
89 |
-
|
90 |
-
$tabs = array(
|
91 |
-
'dashboard' => 'Printful_Admin_Dashboard',
|
92 |
-
'settings' => 'Printful_Admin_Settings',
|
93 |
-
'status' => 'Printful_Admin_Status',
|
94 |
-
'support' => 'Printful_Admin_Support',
|
95 |
-
);
|
96 |
-
|
97 |
-
$tab = ( ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'dashboard' );
|
98 |
-
if ( ! empty( $tabs[ $tab ] ) ) {
|
99 |
-
call_user_func( array( $tabs[ $tab ], 'view' ) );
|
100 |
-
}
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Get the tabs used in printful admin pages
|
105 |
-
* @return array
|
106 |
-
* @throws PrintfulException
|
107 |
-
*/
|
108 |
-
public static function get_tabs() {
|
109 |
-
|
110 |
-
$tabs = array(
|
111 |
-
array( 'name' => __( 'Settings', 'printful' ), 'tab_url' => 'settings' ),
|
112 |
-
array( 'name' => __( 'Status', 'printful' ), 'tab_url' => 'status' ),
|
113 |
-
array( 'name' => __( 'Support', 'printful' ), 'tab_url' => 'support' ),
|
114 |
-
);
|
115 |
-
|
116 |
-
if ( Printful_Integration::instance()->is_connected() ) {
|
117 |
-
array_unshift( $tabs, array( 'name' => __( 'Dashboard', 'printful' ), 'tab_url' => false ) );
|
118 |
-
} else {
|
119 |
-
array_unshift( $tabs, array( 'name' => __( 'Connect', 'printful' ), 'tab_url' => false ) );
|
120 |
-
}
|
121 |
-
|
122 |
-
return $tabs;
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Create the printful toolbar
|
127 |
-
* @param $wp_admin_bar
|
128 |
-
*/
|
129 |
-
public function add_printful_status_toolbar( $wp_admin_bar ) {
|
130 |
-
|
131 |
-
$issueCount = get_transient( Printful_Admin_Status::PF_STATUS_ISSUE_COUNT );
|
132 |
-
|
133 |
-
if ( $issueCount ) {
|
134 |
-
//Add top level menu item
|
135 |
-
$args = array(
|
136 |
-
'id' => 'printful_toolbar',
|
137 |
-
'title' => 'Printful Integration' . ( $issueCount > 0 ? ' <span class="printful-toolbar-issues">' . esc_attr( $issueCount ) . '</span>' : '' ),
|
138 |
-
'href' => get_admin_url( null, 'admin.php?page=' . Printful_Admin::MENU_SLUG_DASHBOARD ),
|
139 |
-
'meta' => array( 'class' => 'printful-toolbar' ),
|
140 |
-
);
|
141 |
-
$wp_admin_bar->add_node( $args );
|
142 |
-
|
143 |
-
//Add status
|
144 |
-
$args = array(
|
145 |
-
'id' => 'printful_toolbar_status',
|
146 |
-
'parent' => 'printful_toolbar',
|
147 |
-
'title' => 'Integration status' . ( $issueCount > 0 ? ' (' . esc_attr( $issueCount ) . _n( ' issue', ' issues', $issueCount ) . ')' : '' ),
|
148 |
-
'href' => get_admin_url( null, 'admin.php?page=' . Printful_Admin::MENU_SLUG_DASHBOARD . '&tab=status' ),
|
149 |
-
'meta' => array( 'class' => 'printful-toolbar-status' ),
|
150 |
-
);
|
151 |
-
$wp_admin_bar->add_node( $args );
|
152 |
-
}
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Load a template file. Extract any variables that are passed
|
157 |
-
* @param $name
|
158 |
-
* @param array $variables
|
159 |
-
*/
|
160 |
-
public static function load_template( $name, $variables = array() ) {
|
161 |
-
|
162 |
-
if ( ! empty( $variables ) ) {
|
163 |
-
extract( $variables );
|
164 |
-
}
|
165 |
-
|
166 |
-
$filename = plugin_dir_path( __FILE__ ) . 'templates/' . $name . '.php';
|
167 |
-
if ( file_exists( $filename ) ) {
|
168 |
-
include( $filename );
|
169 |
-
}
|
170 |
-
}
|
171 |
-
|
172 |
}
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
class Printful_Admin {
|
5 |
+
|
6 |
+
const MENU_TITLE_TOP = 'Printful';
|
7 |
+
const PAGE_TITLE_DASHBOARD = 'Dashboard';
|
8 |
+
const MENU_TITLE_DASHBOARD = 'Dashboard';
|
9 |
+
const MENU_SLUG_DASHBOARD = 'printful-dashboard';
|
10 |
+
const CAPABILITY = 'manage_options';
|
11 |
+
|
12 |
+
public static function init() {
|
13 |
+
$admin = new self;
|
14 |
+
$admin->register_admin();
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Register admin scripts
|
19 |
+
*/
|
20 |
+
public function register_admin() {
|
21 |
+
|
22 |
+
add_action( 'admin_menu', array( $this, 'register_admin_menu_page' ) );
|
23 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_styles' ) );
|
24 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_scripts' ) );
|
25 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'add_global_style' ) );
|
26 |
+
add_action( 'admin_bar_menu', array( $this, 'add_printful_status_toolbar' ), 999 );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Loads stylesheets used in printful admin pages
|
31 |
+
* @param $hook
|
32 |
+
*/
|
33 |
+
public function add_admin_styles($hook) {
|
34 |
+
|
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__ ) );
|
42 |
+
wp_enqueue_style( 'printful-settings', plugins_url( '../assets/css/settings.css', __FILE__ ) );
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Loads stylesheet for printful toolbar element
|
48 |
+
*/
|
49 |
+
public function add_global_style() {
|
50 |
+
if ( is_user_logged_in() ) {
|
51 |
+
wp_enqueue_style( 'printful-global', plugins_url( '../assets/css/global.css', __FILE__ ) );
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Loads scripts used in printful admin pages
|
57 |
+
* @param $hook
|
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__ ) );
|
65 |
+
wp_enqueue_script( 'printful-intercom', plugins_url( '../assets/js/intercom.min.js', __FILE__ ) );
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Register admin menu pages
|
71 |
+
*/
|
72 |
+
public function register_admin_menu_page() {
|
73 |
+
|
74 |
+
add_menu_page(
|
75 |
+
__( 'Dashboard', 'printful' ),
|
76 |
+
self::MENU_TITLE_TOP,
|
77 |
+
self::CAPABILITY,
|
78 |
+
self::MENU_SLUG_DASHBOARD,
|
79 |
+
array( 'Printful_Admin', 'route' ),
|
80 |
+
Printful_Base::get_asset_url() . 'images/printful-menu-icon.png',
|
81 |
+
58
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Route the tabs
|
87 |
+
*/
|
88 |
+
public static function route() {
|
89 |
+
|
90 |
+
$tabs = array(
|
91 |
+
'dashboard' => 'Printful_Admin_Dashboard',
|
92 |
+
'settings' => 'Printful_Admin_Settings',
|
93 |
+
'status' => 'Printful_Admin_Status',
|
94 |
+
'support' => 'Printful_Admin_Support',
|
95 |
+
);
|
96 |
+
|
97 |
+
$tab = ( ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'dashboard' );
|
98 |
+
if ( ! empty( $tabs[ $tab ] ) ) {
|
99 |
+
call_user_func( array( $tabs[ $tab ], 'view' ) );
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Get the tabs used in printful admin pages
|
105 |
+
* @return array
|
106 |
+
* @throws PrintfulException
|
107 |
+
*/
|
108 |
+
public static function get_tabs() {
|
109 |
+
|
110 |
+
$tabs = array(
|
111 |
+
array( 'name' => __( 'Settings', 'printful' ), 'tab_url' => 'settings' ),
|
112 |
+
array( 'name' => __( 'Status', 'printful' ), 'tab_url' => 'status' ),
|
113 |
+
array( 'name' => __( 'Support', 'printful' ), 'tab_url' => 'support' ),
|
114 |
+
);
|
115 |
+
|
116 |
+
if ( Printful_Integration::instance()->is_connected() ) {
|
117 |
+
array_unshift( $tabs, array( 'name' => __( 'Dashboard', 'printful' ), 'tab_url' => false ) );
|
118 |
+
} else {
|
119 |
+
array_unshift( $tabs, array( 'name' => __( 'Connect', 'printful' ), 'tab_url' => false ) );
|
120 |
+
}
|
121 |
+
|
122 |
+
return $tabs;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Create the printful toolbar
|
127 |
+
* @param $wp_admin_bar
|
128 |
+
*/
|
129 |
+
public function add_printful_status_toolbar( $wp_admin_bar ) {
|
130 |
+
|
131 |
+
$issueCount = get_transient( Printful_Admin_Status::PF_STATUS_ISSUE_COUNT );
|
132 |
+
|
133 |
+
if ( $issueCount ) {
|
134 |
+
//Add top level menu item
|
135 |
+
$args = array(
|
136 |
+
'id' => 'printful_toolbar',
|
137 |
+
'title' => 'Printful Integration' . ( $issueCount > 0 ? ' <span class="printful-toolbar-issues">' . esc_attr( $issueCount ) . '</span>' : '' ),
|
138 |
+
'href' => get_admin_url( null, 'admin.php?page=' . Printful_Admin::MENU_SLUG_DASHBOARD ),
|
139 |
+
'meta' => array( 'class' => 'printful-toolbar' ),
|
140 |
+
);
|
141 |
+
$wp_admin_bar->add_node( $args );
|
142 |
+
|
143 |
+
//Add status
|
144 |
+
$args = array(
|
145 |
+
'id' => 'printful_toolbar_status',
|
146 |
+
'parent' => 'printful_toolbar',
|
147 |
+
'title' => 'Integration status' . ( $issueCount > 0 ? ' (' . esc_attr( $issueCount ) . _n( ' issue', ' issues', $issueCount ) . ')' : '' ),
|
148 |
+
'href' => get_admin_url( null, 'admin.php?page=' . Printful_Admin::MENU_SLUG_DASHBOARD . '&tab=status' ),
|
149 |
+
'meta' => array( 'class' => 'printful-toolbar-status' ),
|
150 |
+
);
|
151 |
+
$wp_admin_bar->add_node( $args );
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Load a template file. Extract any variables that are passed
|
157 |
+
* @param $name
|
158 |
+
* @param array $variables
|
159 |
+
*/
|
160 |
+
public static function load_template( $name, $variables = array() ) {
|
161 |
+
|
162 |
+
if ( ! empty( $variables ) ) {
|
163 |
+
extract( $variables );
|
164 |
+
}
|
165 |
+
|
166 |
+
$filename = plugin_dir_path( __FILE__ ) . 'templates/' . $name . '.php';
|
167 |
+
if ( file_exists( $filename ) ) {
|
168 |
+
include( $filename );
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
}
|
includes/class-printful-client.php
CHANGED
@@ -1,192 +1,192 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Printful API client
|
6 |
-
*/
|
7 |
-
class Printful_Client {
|
8 |
-
|
9 |
-
private $key = false;
|
10 |
-
private $lastResponseRaw;
|
11 |
-
private $lastResponse;
|
12 |
-
private $userAgent = 'Printful WooCommerce Plugin';
|
13 |
-
private $apiUrl;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @param string $key Printful Store API key
|
17 |
-
* @param bool|string $disable_ssl Force HTTP instead of HTTPS for API requests
|
18 |
-
*
|
19 |
-
* @throws PrintfulException if the library failed to initialize
|
20 |
-
*/
|
21 |
-
public function __construct( $key = '', $disable_ssl = false ) {
|
22 |
-
|
23 |
-
$key = (string) $key;
|
24 |
-
|
25 |
-
$this->userAgent .= ' ' . Printful_Base::VERSION . ' (WP ' . get_bloginfo( 'version' ) . ' + WC ' . WC()->version . ')';
|
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 ( strlen( $key ) < 32 ) {
|
31 |
-
throw new PrintfulException( 'Missing or invalid Printful store key!' );
|
32 |
-
}
|
33 |
-
$this->key = $key;
|
34 |
-
|
35 |
-
if ( $disable_ssl ) {
|
36 |
-
$this->apiUrl = str_replace( 'https://', 'http://', $this->apiUrl );
|
37 |
-
}
|
38 |
-
|
39 |
-
//setup api host
|
40 |
-
$this->apiUrl = Printful_Base::get_printful_api_host();
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Returns total available item count from the last request if it supports paging (e.g order list) or null otherwise.
|
45 |
-
*
|
46 |
-
* @return int|null Item count
|
47 |
-
*/
|
48 |
-
public function getItemCount() {
|
49 |
-
return isset( $this->lastResponse['paging']['total'] ) ? $this->lastResponse['paging']['total'] : null;
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Perform a GET request to the API
|
54 |
-
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
55 |
-
* @param array $params Additional GET parameters as an associative array
|
56 |
-
* @return mixed API response
|
57 |
-
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
58 |
-
* @throws PrintfulException if the API call has failed or the response is invalid
|
59 |
-
*/
|
60 |
-
public function get( $path, $params = array() ) {
|
61 |
-
return $this->request( 'GET', $path, $params );
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Perform a DELETE request to the API
|
66 |
-
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
67 |
-
* @param array $params Additional GET parameters as an associative array
|
68 |
-
* @return mixed API response
|
69 |
-
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
70 |
-
* @throws PrintfulException if the API call has failed or the response is invalid
|
71 |
-
*/
|
72 |
-
public function delete( $path, $params = array() ) {
|
73 |
-
return $this->request( 'DELETE', $path, $params );
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Perform a POST request to the API
|
78 |
-
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
79 |
-
* @param array $data Request body data as an associative array
|
80 |
-
* @param array $params Additional GET parameters as an associative array
|
81 |
-
* @return mixed API response
|
82 |
-
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
83 |
-
* @throws PrintfulException if the API call has failed or the response is invalid
|
84 |
-
*/
|
85 |
-
public function post( $path, $data = array(), $params = array() ) {
|
86 |
-
return $this->request( 'POST', $path, $params, $data );
|
87 |
-
}
|
88 |
-
/**
|
89 |
-
* Perform a PUT request to the API
|
90 |
-
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
91 |
-
* @param array $data Request body data as an associative array
|
92 |
-
* @param array $params Additional GET parameters as an associative array
|
93 |
-
* @return mixed API response
|
94 |
-
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
95 |
-
* @throws PrintfulException if the API call has failed or the response is invalid
|
96 |
-
*/
|
97 |
-
public function put( $path, $data = array(), $params = array() ) {
|
98 |
-
return $this->request( 'PUT', $path, $params, $data );
|
99 |
-
}
|
100 |
-
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Perform a PATCH request to the API
|
104 |
-
* @param string $path Request path
|
105 |
-
* @param array $data Request body data as an associative array
|
106 |
-
* @param array $params
|
107 |
-
* @return mixed API response
|
108 |
-
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
109 |
-
* @throws PrintfulException if the API call has failed or the response is invalid
|
110 |
-
*/
|
111 |
-
public function patch( $path, $data = array(), $params = array() )
|
112 |
-
{
|
113 |
-
return $this->request( 'PATCH', $path, $params, $data );
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Return raw response data from the last request
|
118 |
-
* @return string|null Response data
|
119 |
-
*/
|
120 |
-
public function getLastResponseRaw() {
|
121 |
-
return $this->lastResponseRaw;
|
122 |
-
}
|
123 |
-
/**
|
124 |
-
* Return decoded response data from the last request
|
125 |
-
* @return array|null Response data
|
126 |
-
*/
|
127 |
-
public function getLastResponse() {
|
128 |
-
return $this->lastResponse;
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Internal request implementation
|
133 |
-
*
|
134 |
-
* @param $method
|
135 |
-
* @param $path
|
136 |
-
* @param array $params
|
137 |
-
* @param null $data
|
138 |
-
*
|
139 |
-
* @return
|
140 |
-
* @throws PrintfulApiException
|
141 |
-
* @throws PrintfulException
|
142 |
-
*/
|
143 |
-
private function request( $method, $path, array $params = array(), $data = null ) {
|
144 |
-
|
145 |
-
$this->lastResponseRaw = null;
|
146 |
-
$this->lastResponse = null;
|
147 |
-
|
148 |
-
$url = trim( $path, '/' );
|
149 |
-
|
150 |
-
if ( ! empty( $params ) ) {
|
151 |
-
$url .= '?' . http_build_query( $params );
|
152 |
-
}
|
153 |
-
|
154 |
-
$request = array(
|
155 |
-
'timeout' => 10,
|
156 |
-
'user-agent' => $this->userAgent,
|
157 |
-
'method' => $method,
|
158 |
-
'headers' => array( 'Authorization' => 'Basic ' . base64_encode( $this->key ) ),
|
159 |
-
'body' => $data !== null ? json_encode( $data ) : null,
|
160 |
-
);
|
161 |
-
|
162 |
-
$result = wp_remote_get( $this->apiUrl . $url, $request );
|
163 |
-
|
164 |
-
//allow other methods to hook in on the api result
|
165 |
-
$result = apply_filters( 'printful_api_result', $result, $method, $this->apiUrl . $url, $request );
|
166 |
-
|
167 |
-
if ( is_wp_error( $result ) ) {
|
168 |
-
throw new PrintfulException( "API request failed - " . $result->get_error_message() );
|
169 |
-
}
|
170 |
-
$this->lastResponseRaw = $result['body'];
|
171 |
-
$this->lastResponse = $response = json_decode( $result['body'], true );
|
172 |
-
|
173 |
-
if ( ! isset( $response['code'], $response['result'] ) ) {
|
174 |
-
throw new PrintfulException( 'Invalid API response' );
|
175 |
-
}
|
176 |
-
$status = (int) $response['code'];
|
177 |
-
if ( $status < 200 || $status >= 300 ) {
|
178 |
-
throw new PrintfulApiException( (string) $response['result'], $status );
|
179 |
-
}
|
180 |
-
|
181 |
-
return $response['result'];
|
182 |
-
}
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* Class PrintfulException Generic Printful exception
|
187 |
-
*/
|
188 |
-
class PrintfulException extends Exception {}
|
189 |
-
/**
|
190 |
-
* Class PrintfulException Printful exception returned from the API
|
191 |
-
*/
|
192 |
class PrintfulApiException extends PrintfulException {}
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Printful API client
|
6 |
+
*/
|
7 |
+
class Printful_Client {
|
8 |
+
|
9 |
+
private $key = false;
|
10 |
+
private $lastResponseRaw;
|
11 |
+
private $lastResponse;
|
12 |
+
private $userAgent = 'Printful WooCommerce Plugin';
|
13 |
+
private $apiUrl;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param string $key Printful Store API key
|
17 |
+
* @param bool|string $disable_ssl Force HTTP instead of HTTPS for API requests
|
18 |
+
*
|
19 |
+
* @throws PrintfulException if the library failed to initialize
|
20 |
+
*/
|
21 |
+
public function __construct( $key = '', $disable_ssl = false ) {
|
22 |
+
|
23 |
+
$key = (string) $key;
|
24 |
+
|
25 |
+
$this->userAgent .= ' ' . Printful_Base::VERSION . ' (WP ' . get_bloginfo( 'version' ) . ' + WC ' . WC()->version . ')';
|
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 ( strlen( $key ) < 32 ) {
|
31 |
+
throw new PrintfulException( 'Missing or invalid Printful store key!' );
|
32 |
+
}
|
33 |
+
$this->key = $key;
|
34 |
+
|
35 |
+
if ( $disable_ssl ) {
|
36 |
+
$this->apiUrl = str_replace( 'https://', 'http://', $this->apiUrl );
|
37 |
+
}
|
38 |
+
|
39 |
+
//setup api host
|
40 |
+
$this->apiUrl = Printful_Base::get_printful_api_host();
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Returns total available item count from the last request if it supports paging (e.g order list) or null otherwise.
|
45 |
+
*
|
46 |
+
* @return int|null Item count
|
47 |
+
*/
|
48 |
+
public function getItemCount() {
|
49 |
+
return isset( $this->lastResponse['paging']['total'] ) ? $this->lastResponse['paging']['total'] : null;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Perform a GET request to the API
|
54 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
55 |
+
* @param array $params Additional GET parameters as an associative array
|
56 |
+
* @return mixed API response
|
57 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
58 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
59 |
+
*/
|
60 |
+
public function get( $path, $params = array() ) {
|
61 |
+
return $this->request( 'GET', $path, $params );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Perform a DELETE request to the API
|
66 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
67 |
+
* @param array $params Additional GET parameters as an associative array
|
68 |
+
* @return mixed API response
|
69 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
70 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
71 |
+
*/
|
72 |
+
public function delete( $path, $params = array() ) {
|
73 |
+
return $this->request( 'DELETE', $path, $params );
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Perform a POST request to the API
|
78 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
79 |
+
* @param array $data Request body data as an associative array
|
80 |
+
* @param array $params Additional GET parameters as an associative array
|
81 |
+
* @return mixed API response
|
82 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
83 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
84 |
+
*/
|
85 |
+
public function post( $path, $data = array(), $params = array() ) {
|
86 |
+
return $this->request( 'POST', $path, $params, $data );
|
87 |
+
}
|
88 |
+
/**
|
89 |
+
* Perform a PUT request to the API
|
90 |
+
* @param string $path Request path (e.g. 'orders' or 'orders/123')
|
91 |
+
* @param array $data Request body data as an associative array
|
92 |
+
* @param array $params Additional GET parameters as an associative array
|
93 |
+
* @return mixed API response
|
94 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
95 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
96 |
+
*/
|
97 |
+
public function put( $path, $data = array(), $params = array() ) {
|
98 |
+
return $this->request( 'PUT', $path, $params, $data );
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Perform a PATCH request to the API
|
104 |
+
* @param string $path Request path
|
105 |
+
* @param array $data Request body data as an associative array
|
106 |
+
* @param array $params
|
107 |
+
* @return mixed API response
|
108 |
+
* @throws PrintfulApiException if the API call status code is not in the 2xx range
|
109 |
+
* @throws PrintfulException if the API call has failed or the response is invalid
|
110 |
+
*/
|
111 |
+
public function patch( $path, $data = array(), $params = array() )
|
112 |
+
{
|
113 |
+
return $this->request( 'PATCH', $path, $params, $data );
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Return raw response data from the last request
|
118 |
+
* @return string|null Response data
|
119 |
+
*/
|
120 |
+
public function getLastResponseRaw() {
|
121 |
+
return $this->lastResponseRaw;
|
122 |
+
}
|
123 |
+
/**
|
124 |
+
* Return decoded response data from the last request
|
125 |
+
* @return array|null Response data
|
126 |
+
*/
|
127 |
+
public function getLastResponse() {
|
128 |
+
return $this->lastResponse;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Internal request implementation
|
133 |
+
*
|
134 |
+
* @param $method
|
135 |
+
* @param $path
|
136 |
+
* @param array $params
|
137 |
+
* @param null $data
|
138 |
+
*
|
139 |
+
* @return
|
140 |
+
* @throws PrintfulApiException
|
141 |
+
* @throws PrintfulException
|
142 |
+
*/
|
143 |
+
private function request( $method, $path, array $params = array(), $data = null ) {
|
144 |
+
|
145 |
+
$this->lastResponseRaw = null;
|
146 |
+
$this->lastResponse = null;
|
147 |
+
|
148 |
+
$url = trim( $path, '/' );
|
149 |
+
|
150 |
+
if ( ! empty( $params ) ) {
|
151 |
+
$url .= '?' . http_build_query( $params );
|
152 |
+
}
|
153 |
+
|
154 |
+
$request = array(
|
155 |
+
'timeout' => 10,
|
156 |
+
'user-agent' => $this->userAgent,
|
157 |
+
'method' => $method,
|
158 |
+
'headers' => array( 'Authorization' => 'Basic ' . base64_encode( $this->key ) ),
|
159 |
+
'body' => $data !== null ? json_encode( $data ) : null,
|
160 |
+
);
|
161 |
+
|
162 |
+
$result = wp_remote_get( $this->apiUrl . $url, $request );
|
163 |
+
|
164 |
+
//allow other methods to hook in on the api result
|
165 |
+
$result = apply_filters( 'printful_api_result', $result, $method, $this->apiUrl . $url, $request );
|
166 |
+
|
167 |
+
if ( is_wp_error( $result ) ) {
|
168 |
+
throw new PrintfulException( "API request failed - " . $result->get_error_message() );
|
169 |
+
}
|
170 |
+
$this->lastResponseRaw = $result['body'];
|
171 |
+
$this->lastResponse = $response = json_decode( $result['body'], true );
|
172 |
+
|
173 |
+
if ( ! isset( $response['code'], $response['result'] ) ) {
|
174 |
+
throw new PrintfulException( 'Invalid API response' );
|
175 |
+
}
|
176 |
+
$status = (int) $response['code'];
|
177 |
+
if ( $status < 200 || $status >= 300 ) {
|
178 |
+
throw new PrintfulApiException( (string) $response['result'], $status );
|
179 |
+
}
|
180 |
+
|
181 |
+
return $response['result'];
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Class PrintfulException Generic Printful exception
|
187 |
+
*/
|
188 |
+
class PrintfulException extends Exception {}
|
189 |
+
/**
|
190 |
+
* Class PrintfulException Printful exception returned from the API
|
191 |
+
*/
|
192 |
class PrintfulApiException extends PrintfulException {}
|
includes/class-printful-integration.php
CHANGED
@@ -1,165 +1,165 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
-
|
4 |
-
class Printful_Integration
|
5 |
-
{
|
6 |
-
const PF_API_CONNECT_STATUS = 'printful_api_connect_status';
|
7 |
-
const PF_CONNECT_ERROR = 'printful_connect_error';
|
8 |
-
|
9 |
-
public static $_instance;
|
10 |
-
|
11 |
-
public static function instance() {
|
12 |
-
if ( is_null( self::$_instance ) ) {
|
13 |
-
self::$_instance = new self();
|
14 |
-
}
|
15 |
-
|
16 |
-
return self::$_instance;
|
17 |
-
}
|
18 |
-
|
19 |
-
public function __construct() {
|
20 |
-
self::$_instance = $this;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @return Printful_Client
|
25 |
-
* @throws PrintfulException
|
26 |
-
*/
|
27 |
-
public function get_client() {
|
28 |
-
|
29 |
-
require_once 'class-printful-client.php';
|
30 |
-
$client = new Printful_Client( $this->get_option( 'printful_key' ), $this->get_option( 'disable_ssl' ) == 'yes' );
|
31 |
-
|
32 |
-
return $client;
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Check if the connection to printful is working
|
37 |
-
* @param bool $force
|
38 |
-
* @return bool
|
39 |
-
* @throws PrintfulException
|
40 |
-
*/
|
41 |
-
public function is_connected( $force = false ) {
|
42 |
-
|
43 |
-
$api_key = $this->get_option( 'printful_key' );
|
44 |
-
|
45 |
-
//dont need to show error - the plugin is simply not setup
|
46 |
-
if ( empty( $api_key ) ) {
|
47 |
-
return false;
|
48 |
-
}
|
49 |
-
|
50 |
-
//validate length, show error
|
51 |
-
if ( strlen( $api_key ) != 36 ) {
|
52 |
-
$message = 'Invalid API key - the key must be 36 characters long. Please ensure that your API key in <a href="%s">Settings</a> matches the one in your <a href="%s">Printful dashboard</a>.';
|
53 |
-
$settings_url = admin_url( 'admin.php?page=printful-dashboard&tab=settings' );
|
54 |
-
$printful_url = Printful_Base::get_printful_host() . 'dashboard/';
|
55 |
-
$this->set_connect_error(sprintf( $message, $settings_url, $printful_url ) );
|
56 |
-
|
57 |
-
return false;
|
58 |
-
}
|
59 |
-
|
60 |
-
//show connect status from cache
|
61 |
-
if ( ! $force ) {
|
62 |
-
$connected = get_transient( self::PF_API_CONNECT_STATUS );
|
63 |
-
if ( $connected && $connected['status'] == 1 ) {
|
64 |
-
$this->clear_connect_error();
|
65 |
-
|
66 |
-
return true;
|
67 |
-
} else if ( $connected && $connected['status'] == 0 ) { //try again in a minute
|
68 |
-
return false;
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
$client = $this->get_client();
|
73 |
-
$response = false;
|
74 |
-
|
75 |
-
//attempt to connect to printful to verify the API key
|
76 |
-
try {
|
77 |
-
$storeData = $client->get( 'store' );
|
78 |
-
if ( ! empty( $storeData ) && $storeData['type'] == 'woocommerce') {
|
79 |
-
$response = true;
|
80 |
-
$this->clear_connect_error();
|
81 |
-
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 1 ) ); //no expiry
|
82 |
-
} elseif ( $storeData['type'] != 'woocommerce' ) {
|
83 |
-
$message = 'Invalid API key. This API key belongs to a ' . ucfirst( $storeData['type'] ) . ' store. Please copy the correct key from <a href="%s">Printful store settings</a> and enter it in the <a href="%s">Printful plugin settings</a>';
|
84 |
-
$settings_url = admin_url( 'admin.php?page=printful-dashboard&tab=settings' );
|
85 |
-
$printful_url = Printful_Base::get_printful_host() . 'dashboard/store';
|
86 |
-
$this->set_connect_error( sprintf( $message, $settings_url, $printful_url ) );
|
87 |
-
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 0 ), MINUTE_IN_SECONDS ); //try again in 1 minute
|
88 |
-
}
|
89 |
-
} catch ( Exception $e ) {
|
90 |
-
|
91 |
-
if ( $e->getCode() == 401 ) {
|
92 |
-
$message = 'Invalid API key. Please ensure that your API key in <a href="%s">Printful plugin settings</a> matches the one in your <a href="%s">Printful store settings</a>.';
|
93 |
-
$settings_url = admin_url( 'admin.php?page=printful-dashboard&tab=settings' );
|
94 |
-
$printful_url = Printful_Base::get_printful_host() . 'dashboard/store';
|
95 |
-
$this->set_connect_error( sprintf( $message, $settings_url, $printful_url ) );
|
96 |
-
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 0 ), MINUTE_IN_SECONDS ); //try again in 1 minute
|
97 |
-
} else {
|
98 |
-
$this->set_connect_error( 'Could not connect to Printful API. Please try again later. (Error ' . $e->getCode() . ': ' . $e->getMessage() . ')' );
|
99 |
-
}
|
100 |
-
|
101 |
-
//do nothing
|
102 |
-
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 0 ), MINUTE_IN_SECONDS ); //try again in 1 minute
|
103 |
-
}
|
104 |
-
|
105 |
-
return $response;
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Update connect error message
|
110 |
-
* @param string $error
|
111 |
-
*/
|
112 |
-
public function set_connect_error($error = '') {
|
113 |
-
update_option( self::PF_CONNECT_ERROR, $error );
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Get current connect error message
|
118 |
-
*/
|
119 |
-
public function get_connect_error() {
|
120 |
-
return get_option( self::PF_CONNECT_ERROR, false );
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Remove option used for storing current connect error
|
125 |
-
*/
|
126 |
-
public function clear_connect_error() {
|
127 |
-
delete_option( self::PF_CONNECT_ERROR );
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* AJAX call endpoint for connect status check
|
132 |
-
* @throws PrintfulException
|
133 |
-
*/
|
134 |
-
public static function ajax_force_check_connect_status() {
|
135 |
-
if ( Printful_Integration::instance()->is_connected( true ) ) {
|
136 |
-
die( 'OK' );
|
137 |
-
}
|
138 |
-
|
139 |
-
die( 'FAIL' );
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Wrapper method for getting an option
|
144 |
-
* @param $name
|
145 |
-
* @param array $default
|
146 |
-
* @return bool
|
147 |
-
*/
|
148 |
-
public function get_option( $name, $default = array() ) {
|
149 |
-
$options = get_option( 'woocommerce_printful_settings', $default );
|
150 |
-
if ( ! empty( $options[ $name ] ) ) {
|
151 |
-
return $options[ $name ];
|
152 |
-
}
|
153 |
-
|
154 |
-
return false;
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Save the setting
|
159 |
-
* @param $settings
|
160 |
-
*/
|
161 |
-
public function update_settings( $settings ) {
|
162 |
-
delete_transient( self::PF_API_CONNECT_STATUS ); //remove the successful API status since API key could have changed
|
163 |
-
update_option( 'woocommerce_printful_settings', $settings );
|
164 |
-
}
|
165 |
}
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
class Printful_Integration
|
5 |
+
{
|
6 |
+
const PF_API_CONNECT_STATUS = 'printful_api_connect_status';
|
7 |
+
const PF_CONNECT_ERROR = 'printful_connect_error';
|
8 |
+
|
9 |
+
public static $_instance;
|
10 |
+
|
11 |
+
public static function instance() {
|
12 |
+
if ( is_null( self::$_instance ) ) {
|
13 |
+
self::$_instance = new self();
|
14 |
+
}
|
15 |
+
|
16 |
+
return self::$_instance;
|
17 |
+
}
|
18 |
+
|
19 |
+
public function __construct() {
|
20 |
+
self::$_instance = $this;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @return Printful_Client
|
25 |
+
* @throws PrintfulException
|
26 |
+
*/
|
27 |
+
public function get_client() {
|
28 |
+
|
29 |
+
require_once 'class-printful-client.php';
|
30 |
+
$client = new Printful_Client( $this->get_option( 'printful_key' ), $this->get_option( 'disable_ssl' ) == 'yes' );
|
31 |
+
|
32 |
+
return $client;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Check if the connection to printful is working
|
37 |
+
* @param bool $force
|
38 |
+
* @return bool
|
39 |
+
* @throws PrintfulException
|
40 |
+
*/
|
41 |
+
public function is_connected( $force = false ) {
|
42 |
+
|
43 |
+
$api_key = $this->get_option( 'printful_key' );
|
44 |
+
|
45 |
+
//dont need to show error - the plugin is simply not setup
|
46 |
+
if ( empty( $api_key ) ) {
|
47 |
+
return false;
|
48 |
+
}
|
49 |
+
|
50 |
+
//validate length, show error
|
51 |
+
if ( strlen( $api_key ) != 36 ) {
|
52 |
+
$message = 'Invalid API key - the key must be 36 characters long. Please ensure that your API key in <a href="%s">Settings</a> matches the one in your <a href="%s">Printful dashboard</a>.';
|
53 |
+
$settings_url = admin_url( 'admin.php?page=printful-dashboard&tab=settings' );
|
54 |
+
$printful_url = Printful_Base::get_printful_host() . 'dashboard/';
|
55 |
+
$this->set_connect_error(sprintf( $message, $settings_url, $printful_url ) );
|
56 |
+
|
57 |
+
return false;
|
58 |
+
}
|
59 |
+
|
60 |
+
//show connect status from cache
|
61 |
+
if ( ! $force ) {
|
62 |
+
$connected = get_transient( self::PF_API_CONNECT_STATUS );
|
63 |
+
if ( $connected && $connected['status'] == 1 ) {
|
64 |
+
$this->clear_connect_error();
|
65 |
+
|
66 |
+
return true;
|
67 |
+
} else if ( $connected && $connected['status'] == 0 ) { //try again in a minute
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
$client = $this->get_client();
|
73 |
+
$response = false;
|
74 |
+
|
75 |
+
//attempt to connect to printful to verify the API key
|
76 |
+
try {
|
77 |
+
$storeData = $client->get( 'store' );
|
78 |
+
if ( ! empty( $storeData ) && $storeData['type'] == 'woocommerce') {
|
79 |
+
$response = true;
|
80 |
+
$this->clear_connect_error();
|
81 |
+
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 1 ) ); //no expiry
|
82 |
+
} elseif ( $storeData['type'] != 'woocommerce' ) {
|
83 |
+
$message = 'Invalid API key. This API key belongs to a ' . ucfirst( $storeData['type'] ) . ' store. Please copy the correct key from <a href="%s">Printful store settings</a> and enter it in the <a href="%s">Printful plugin settings</a>';
|
84 |
+
$settings_url = admin_url( 'admin.php?page=printful-dashboard&tab=settings' );
|
85 |
+
$printful_url = Printful_Base::get_printful_host() . 'dashboard/store';
|
86 |
+
$this->set_connect_error( sprintf( $message, $settings_url, $printful_url ) );
|
87 |
+
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 0 ), MINUTE_IN_SECONDS ); //try again in 1 minute
|
88 |
+
}
|
89 |
+
} catch ( Exception $e ) {
|
90 |
+
|
91 |
+
if ( $e->getCode() == 401 ) {
|
92 |
+
$message = 'Invalid API key. Please ensure that your API key in <a href="%s">Printful plugin settings</a> matches the one in your <a href="%s">Printful store settings</a>.';
|
93 |
+
$settings_url = admin_url( 'admin.php?page=printful-dashboard&tab=settings' );
|
94 |
+
$printful_url = Printful_Base::get_printful_host() . 'dashboard/store';
|
95 |
+
$this->set_connect_error( sprintf( $message, $settings_url, $printful_url ) );
|
96 |
+
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 0 ), MINUTE_IN_SECONDS ); //try again in 1 minute
|
97 |
+
} else {
|
98 |
+
$this->set_connect_error( 'Could not connect to Printful API. Please try again later. (Error ' . $e->getCode() . ': ' . $e->getMessage() . ')' );
|
99 |
+
}
|
100 |
+
|
101 |
+
//do nothing
|
102 |
+
set_transient( self::PF_API_CONNECT_STATUS, array( 'status' => 0 ), MINUTE_IN_SECONDS ); //try again in 1 minute
|
103 |
+
}
|
104 |
+
|
105 |
+
return $response;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Update connect error message
|
110 |
+
* @param string $error
|
111 |
+
*/
|
112 |
+
public function set_connect_error($error = '') {
|
113 |
+
update_option( self::PF_CONNECT_ERROR, $error );
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Get current connect error message
|
118 |
+
*/
|
119 |
+
public function get_connect_error() {
|
120 |
+
return get_option( self::PF_CONNECT_ERROR, false );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Remove option used for storing current connect error
|
125 |
+
*/
|
126 |
+
public function clear_connect_error() {
|
127 |
+
delete_option( self::PF_CONNECT_ERROR );
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* AJAX call endpoint for connect status check
|
132 |
+
* @throws PrintfulException
|
133 |
+
*/
|
134 |
+
public static function ajax_force_check_connect_status() {
|
135 |
+
if ( Printful_Integration::instance()->is_connected( true ) ) {
|
136 |
+
die( 'OK' );
|
137 |
+
}
|
138 |
+
|
139 |
+
die( 'FAIL' );
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Wrapper method for getting an option
|
144 |
+
* @param $name
|
145 |
+
* @param array $default
|
146 |
+
* @return bool
|
147 |
+
*/
|
148 |
+
public function get_option( $name, $default = array() ) {
|
149 |
+
$options = get_option( 'woocommerce_printful_settings', $default );
|
150 |
+
if ( ! empty( $options[ $name ] ) ) {
|
151 |
+
return $options[ $name ];
|
152 |
+
}
|
153 |
+
|
154 |
+
return false;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Save the setting
|
159 |
+
* @param $settings
|
160 |
+
*/
|
161 |
+
public function update_settings( $settings ) {
|
162 |
+
delete_transient( self::PF_API_CONNECT_STATUS ); //remove the successful API status since API key could have changed
|
163 |
+
update_option( 'woocommerce_printful_settings', $settings );
|
164 |
+
}
|
165 |
}
|
includes/class-printful-request-log.php
CHANGED
@@ -1,151 +1,151 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
-
|
4 |
-
class Printful_Request_log {
|
5 |
-
|
6 |
-
const PF_USER_AGENT = 'Printful WooCommerce Integration';
|
7 |
-
const PF_OPTION_LAST_API_RESPONSE = 'printful_last_api_response';
|
8 |
-
const PF_OPTION_INCOMING_API_REQUEST_LOG = 'printful_incoming_api_request_log';
|
9 |
-
const PF_OPTION_OUTGOING_API_REQUEST_LOG = 'printful_outgoing_api_request_log';
|
10 |
-
const PF_INCOMING_API_ERRORS = 'printful-incoming-api-errors';
|
11 |
-
const PF_OUTGOING_API_ERRORS = 'printful-outgoing-api-errors';
|
12 |
-
|
13 |
-
public static function init() {
|
14 |
-
$printful_log = new self;
|
15 |
-
add_filter( 'woocommerce_api_serve_request', array( $printful_log, 'log_incoming_printful_api_requests' ), 10, 3 );
|
16 |
-
add_filter( 'printful_api_result', array( $printful_log, 'log_outgoing_printful_api_requests'), 10, 4 );
|
17 |
-
}
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Log printful API errors and save the last 20 API responses
|
21 |
-
* @param $served
|
22 |
-
* @param $result
|
23 |
-
* @param $request
|
24 |
-
*
|
25 |
-
* @return mixed
|
26 |
-
*/
|
27 |
-
public function log_incoming_printful_api_requests( $served, $result, $request ) {
|
28 |
-
|
29 |
-
if ( ! $this->isPrintfulApiRequest( $request ) ) {
|
30 |
-
return $served;
|
31 |
-
}
|
32 |
-
|
33 |
-
$last_api_response = get_option( self::PF_OPTION_LAST_API_RESPONSE, false );
|
34 |
-
$response_hash = md5( serialize( array( 'request' => $request, 'results' => $result ) ) );
|
35 |
-
|
36 |
-
if ( $last_api_response == $response_hash ) { //do not allow the same response to be logged twice
|
37 |
-
return $served;
|
38 |
-
}
|
39 |
-
|
40 |
-
//save full error to WC logs
|
41 |
-
if ( ! empty( $result['errors'] ) ) {
|
42 |
-
$this->save_to_wc_log( $request, $result, self::PF_INCOMING_API_ERRORS );
|
43 |
-
}
|
44 |
-
|
45 |
-
//save summary in database to be easily accessible for status page
|
46 |
-
$this->save_to_printful_log( $request->method . ' ' . $request->path, $result, $response_hash, self::PF_OPTION_INCOMING_API_REQUEST_LOG );
|
47 |
-
|
48 |
-
return $served; //we avoid changing the result
|
49 |
-
}
|
50 |
-
|
51 |
-
|
52 |
-
/**
|
53 |
-
* @param $result
|
54 |
-
* @param $method
|
55 |
-
* @param $url
|
56 |
-
* @param $request
|
57 |
-
* @return array|mixed|object
|
58 |
-
*/
|
59 |
-
public function log_outgoing_printful_api_requests($result, $method, $url, $request) {
|
60 |
-
|
61 |
-
$original_result = $result;
|
62 |
-
$request['path'] = $url;
|
63 |
-
$params_set = null;
|
64 |
-
$code_success = null;
|
65 |
-
|
66 |
-
if ( ! is_wp_error( $result ) ) {
|
67 |
-
$result = json_decode( $result['body'], true );
|
68 |
-
$params_set = ! isset( $result['code'], $result['result'] );
|
69 |
-
$status = (int) $result['code'];
|
70 |
-
$code_success = ( $status < 200 || $status >= 300 );
|
71 |
-
}
|
72 |
-
|
73 |
-
//if the request contains error, log it
|
74 |
-
if ( is_wp_error($result) || $params_set || $code_success ) {
|
75 |
-
$this->save_to_wc_log( $request, $result, self::PF_OUTGOING_API_ERRORS );
|
76 |
-
}
|
77 |
-
|
78 |
-
$response_hash = md5( serialize( array( 'request' => $request, 'results' => $result ) ) );
|
79 |
-
|
80 |
-
//save summary in database to be easily accessible for status page
|
81 |
-
$this->save_to_printful_log( $method . ' ' . $url, $result, $response_hash, self::PF_OPTION_OUTGOING_API_REQUEST_LOG );
|
82 |
-
|
83 |
-
return $original_result; //don't change the result
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Write Printful API request errors to log
|
88 |
-
*
|
89 |
-
* @param $request
|
90 |
-
* @param $result
|
91 |
-
* @param string $context
|
92 |
-
* @return bool
|
93 |
-
*/
|
94 |
-
private function save_to_wc_log( $request, $result, $context ) {
|
95 |
-
|
96 |
-
if ( ! function_exists( 'wc_get_logger' ) ) {
|
97 |
-
return false;
|
98 |
-
}
|
99 |
-
|
100 |
-
$logger = wc_get_logger();
|
101 |
-
$context = array( 'source' => $context );
|
102 |
-
$log_item = array(
|
103 |
-
'request' => (array) $request,
|
104 |
-
'results' => (array) $result,
|
105 |
-
);
|
106 |
-
$logger->error( wc_print_r( $log_item, true ), $context );
|
107 |
-
|
108 |
-
return true;
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Save 20 lasts requests in easily accessible location
|
113 |
-
*
|
114 |
-
* @param $request_title
|
115 |
-
* @param $result
|
116 |
-
* @param $response_hash
|
117 |
-
* @param $log
|
118 |
-
*/
|
119 |
-
private function save_to_printful_log( $request_title, $result, $response_hash, $log ) {
|
120 |
-
|
121 |
-
$request_log = get_option( $log, array() );
|
122 |
-
if ( count( $request_log ) > 20 ) {
|
123 |
-
$request_log = array_slice( $request_log, 1, 19 ); //if there are more than 20, remove the first entry
|
124 |
-
}
|
125 |
-
|
126 |
-
$is_error = is_wp_error($result) || !empty( $result['errors'] );
|
127 |
-
|
128 |
-
$request_log[] = array(
|
129 |
-
'date' => date( 'Y-m-d H:i:s' ),
|
130 |
-
'request' => $request_title,
|
131 |
-
'result' => ( $is_error ? 'ERROR' : 'OK' ),
|
132 |
-
);
|
133 |
-
|
134 |
-
update_option( $log, $request_log );
|
135 |
-
update_option( self::PF_OPTION_LAST_API_RESPONSE, $response_hash );
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Check requests header for indications that this is a printful api request
|
140 |
-
* @param $request
|
141 |
-
* @return bool
|
142 |
-
*/
|
143 |
-
private function isPrintfulApiRequest( $request ) {
|
144 |
-
|
145 |
-
if ( ! empty( $request->headers ) && ! empty( $request->headers['USER_AGENT'] ) && $request->headers['USER_AGENT'] == self::PF_USER_AGENT ) {
|
146 |
-
return true;
|
147 |
-
}
|
148 |
-
|
149 |
-
return false;
|
150 |
-
}
|
151 |
}
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
class Printful_Request_log {
|
5 |
+
|
6 |
+
const PF_USER_AGENT = 'Printful WooCommerce Integration';
|
7 |
+
const PF_OPTION_LAST_API_RESPONSE = 'printful_last_api_response';
|
8 |
+
const PF_OPTION_INCOMING_API_REQUEST_LOG = 'printful_incoming_api_request_log';
|
9 |
+
const PF_OPTION_OUTGOING_API_REQUEST_LOG = 'printful_outgoing_api_request_log';
|
10 |
+
const PF_INCOMING_API_ERRORS = 'printful-incoming-api-errors';
|
11 |
+
const PF_OUTGOING_API_ERRORS = 'printful-outgoing-api-errors';
|
12 |
+
|
13 |
+
public static function init() {
|
14 |
+
$printful_log = new self;
|
15 |
+
add_filter( 'woocommerce_api_serve_request', array( $printful_log, 'log_incoming_printful_api_requests' ), 10, 3 );
|
16 |
+
add_filter( 'printful_api_result', array( $printful_log, 'log_outgoing_printful_api_requests'), 10, 4 );
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Log printful API errors and save the last 20 API responses
|
21 |
+
* @param $served
|
22 |
+
* @param $result
|
23 |
+
* @param $request
|
24 |
+
*
|
25 |
+
* @return mixed
|
26 |
+
*/
|
27 |
+
public function log_incoming_printful_api_requests( $served, $result, $request ) {
|
28 |
+
|
29 |
+
if ( ! $this->isPrintfulApiRequest( $request ) ) {
|
30 |
+
return $served;
|
31 |
+
}
|
32 |
+
|
33 |
+
$last_api_response = get_option( self::PF_OPTION_LAST_API_RESPONSE, false );
|
34 |
+
$response_hash = md5( serialize( array( 'request' => $request, 'results' => $result ) ) );
|
35 |
+
|
36 |
+
if ( $last_api_response == $response_hash ) { //do not allow the same response to be logged twice
|
37 |
+
return $served;
|
38 |
+
}
|
39 |
+
|
40 |
+
//save full error to WC logs
|
41 |
+
if ( ! empty( $result['errors'] ) ) {
|
42 |
+
$this->save_to_wc_log( $request, $result, self::PF_INCOMING_API_ERRORS );
|
43 |
+
}
|
44 |
+
|
45 |
+
//save summary in database to be easily accessible for status page
|
46 |
+
$this->save_to_printful_log( $request->method . ' ' . $request->path, $result, $response_hash, self::PF_OPTION_INCOMING_API_REQUEST_LOG );
|
47 |
+
|
48 |
+
return $served; //we avoid changing the result
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @param $result
|
54 |
+
* @param $method
|
55 |
+
* @param $url
|
56 |
+
* @param $request
|
57 |
+
* @return array|mixed|object
|
58 |
+
*/
|
59 |
+
public function log_outgoing_printful_api_requests($result, $method, $url, $request) {
|
60 |
+
|
61 |
+
$original_result = $result;
|
62 |
+
$request['path'] = $url;
|
63 |
+
$params_set = null;
|
64 |
+
$code_success = null;
|
65 |
+
|
66 |
+
if ( ! is_wp_error( $result ) ) {
|
67 |
+
$result = json_decode( $result['body'], true );
|
68 |
+
$params_set = ! isset( $result['code'], $result['result'] );
|
69 |
+
$status = (int) $result['code'];
|
70 |
+
$code_success = ( $status < 200 || $status >= 300 );
|
71 |
+
}
|
72 |
+
|
73 |
+
//if the request contains error, log it
|
74 |
+
if ( is_wp_error($result) || $params_set || $code_success ) {
|
75 |
+
$this->save_to_wc_log( $request, $result, self::PF_OUTGOING_API_ERRORS );
|
76 |
+
}
|
77 |
+
|
78 |
+
$response_hash = md5( serialize( array( 'request' => $request, 'results' => $result ) ) );
|
79 |
+
|
80 |
+
//save summary in database to be easily accessible for status page
|
81 |
+
$this->save_to_printful_log( $method . ' ' . $url, $result, $response_hash, self::PF_OPTION_OUTGOING_API_REQUEST_LOG );
|
82 |
+
|
83 |
+
return $original_result; //don't change the result
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Write Printful API request errors to log
|
88 |
+
*
|
89 |
+
* @param $request
|
90 |
+
* @param $result
|
91 |
+
* @param string $context
|
92 |
+
* @return bool
|
93 |
+
*/
|
94 |
+
private function save_to_wc_log( $request, $result, $context ) {
|
95 |
+
|
96 |
+
if ( ! function_exists( 'wc_get_logger' ) ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
$logger = wc_get_logger();
|
101 |
+
$context = array( 'source' => $context );
|
102 |
+
$log_item = array(
|
103 |
+
'request' => (array) $request,
|
104 |
+
'results' => (array) $result,
|
105 |
+
);
|
106 |
+
$logger->error( wc_print_r( $log_item, true ), $context );
|
107 |
+
|
108 |
+
return true;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Save 20 lasts requests in easily accessible location
|
113 |
+
*
|
114 |
+
* @param $request_title
|
115 |
+
* @param $result
|
116 |
+
* @param $response_hash
|
117 |
+
* @param $log
|
118 |
+
*/
|
119 |
+
private function save_to_printful_log( $request_title, $result, $response_hash, $log ) {
|
120 |
+
|
121 |
+
$request_log = get_option( $log, array() );
|
122 |
+
if ( count( $request_log ) > 20 ) {
|
123 |
+
$request_log = array_slice( $request_log, 1, 19 ); //if there are more than 20, remove the first entry
|
124 |
+
}
|
125 |
+
|
126 |
+
$is_error = is_wp_error($result) || !empty( $result['errors'] );
|
127 |
+
|
128 |
+
$request_log[] = array(
|
129 |
+
'date' => date( 'Y-m-d H:i:s' ),
|
130 |
+
'request' => $request_title,
|
131 |
+
'result' => ( $is_error ? 'ERROR' : 'OK' ),
|
132 |
+
);
|
133 |
+
|
134 |
+
update_option( $log, $request_log );
|
135 |
+
update_option( self::PF_OPTION_LAST_API_RESPONSE, $response_hash );
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Check requests header for indications that this is a printful api request
|
140 |
+
* @param $request
|
141 |
+
* @return bool
|
142 |
+
*/
|
143 |
+
private function isPrintfulApiRequest( $request ) {
|
144 |
+
|
145 |
+
if ( ! empty( $request->headers ) && ! empty( $request->headers['USER_AGENT'] ) && $request->headers['USER_AGENT'] == self::PF_USER_AGENT ) {
|
146 |
+
return true;
|
147 |
+
}
|
148 |
+
|
149 |
+
return false;
|
150 |
+
}
|
151 |
}
|
includes/class-printful-rest-api-controller.php
CHANGED
@@ -64,6 +64,26 @@ class Printful_REST_API_Controller extends WC_REST_Controller
|
|
64 |
)
|
65 |
) );
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
register_rest_route( $this->namespace, '/' . $this->rest_base . '/version', array(
|
68 |
array(
|
69 |
'methods' => WP_REST_Server::READABLE,
|
@@ -142,7 +162,16 @@ class Printful_REST_API_Controller extends WC_REST_Controller
|
|
142 |
}
|
143 |
|
144 |
//lets do this
|
145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
|
147 |
return array(
|
148 |
'product' => $product,
|
64 |
)
|
65 |
) );
|
66 |
|
67 |
+
register_rest_route( $this->namespace, '/' . $this->rest_base . '/products/(?P<product_id>\d+)/advanced-size-chart', array(
|
68 |
+
array(
|
69 |
+
'methods' => WP_REST_Server::EDITABLE,
|
70 |
+
'callback' => array( $this, 'post_size_guide' ),
|
71 |
+
'permission_callback' => array( $this, 'update_item_permissions_check' ),
|
72 |
+
'show_in_index' => false,
|
73 |
+
'args' => array(
|
74 |
+
'product_id' => array(
|
75 |
+
'description' => __( 'Unique identifier for the resource.', 'printful' ),
|
76 |
+
'type' => 'integer',
|
77 |
+
),
|
78 |
+
'size_chart' => array(
|
79 |
+
'required' => true,
|
80 |
+
'type' => 'object',
|
81 |
+
'description' => __( 'Advanced Printful size guide', 'printful' ),
|
82 |
+
)
|
83 |
+
)
|
84 |
+
)
|
85 |
+
) );
|
86 |
+
|
87 |
register_rest_route( $this->namespace, '/' . $this->rest_base . '/version', array(
|
88 |
array(
|
89 |
'methods' => WP_REST_Server::READABLE,
|
162 |
}
|
163 |
|
164 |
//lets do this
|
165 |
+
if( is_array( $data['size_chart']) ) {
|
166 |
+
// Advanced size guide
|
167 |
+
$payload = addslashes( json_encode( Printful_Size_Guide::process_size_guide_for_storage($data['size_chart'], $product_id ) ) );
|
168 |
+
$metaKey = 'pf_advanced_size_chart';
|
169 |
+
} else {
|
170 |
+
$payload = htmlspecialchars( $data['size_chart'] );
|
171 |
+
$metaKey = 'pf_size_chart';
|
172 |
+
}
|
173 |
+
|
174 |
+
update_post_meta( $product->get_id(), $metaKey, $payload );
|
175 |
|
176 |
return array(
|
177 |
'product' => $product,
|
includes/class-printful-size-chart-tab.php
CHANGED
@@ -1,124 +1,129 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
-
|
4 |
-
class Printful_Size_Chart_Tab {
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Is meta boxes saved once?
|
8 |
-
*
|
9 |
-
* @var boolean
|
10 |
-
*/
|
11 |
-
private static $saved_meta_boxes = false;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Printful_Size_Chart_Tab constructor.
|
15 |
-
*/
|
16 |
-
public static function init() {
|
17 |
-
$size_chart = new self;
|
18 |
-
add_filter( 'woocommerce_product_tabs', array( $size_chart, 'init_size_chart_tab' ) );
|
19 |
-
add_action( 'add_meta_boxes', array( $size_chart, 'init_metabox' ) );
|
20 |
-
add_action( 'save_post', array( $size_chart, 'save_size_chart' ), 1, 2 );
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Initialize meta boxes
|
25 |
-
*/
|
26 |
-
public function init_metabox() {
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
'
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
//
|
94 |
-
if (
|
95 |
-
return;
|
96 |
-
}
|
97 |
-
|
98 |
-
//
|
99 |
-
if (
|
100 |
-
return;
|
101 |
-
}
|
102 |
-
|
103 |
-
// Check the
|
104 |
-
if ( empty( $_POST['
|
105 |
-
return;
|
106 |
-
}
|
107 |
-
|
108 |
-
// Check
|
109 |
-
if (
|
110 |
-
return;
|
111 |
-
}
|
112 |
-
|
113 |
-
// Check
|
114 |
-
if (
|
115 |
-
return;
|
116 |
-
}
|
117 |
-
|
118 |
-
//
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
class Printful_Size_Chart_Tab {
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Is meta boxes saved once?
|
8 |
+
*
|
9 |
+
* @var boolean
|
10 |
+
*/
|
11 |
+
private static $saved_meta_boxes = false;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Printful_Size_Chart_Tab constructor.
|
15 |
+
*/
|
16 |
+
public static function init() {
|
17 |
+
$size_chart = new self;
|
18 |
+
add_filter( 'woocommerce_product_tabs', array( $size_chart, 'init_size_chart_tab' ) );
|
19 |
+
add_action( 'add_meta_boxes', array( $size_chart, 'init_metabox' ) );
|
20 |
+
add_action( 'save_post', array( $size_chart, 'save_size_chart' ), 1, 2 );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Initialize meta boxes
|
25 |
+
*/
|
26 |
+
public function init_metabox() {
|
27 |
+
global $post;
|
28 |
+
// If product has advanced size chart we don't show basic size chart metabox at all
|
29 |
+
if (Printful_Size_Guide::get_size_guide_for_product($post)) {
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
add_meta_box( 'pf_size_chart', __( 'Size chart', 'printful' ), array( $this, 'size_chart_metabox' ), 'product', 'normal' );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @param $tabs
|
37 |
+
*
|
38 |
+
* @return mixed
|
39 |
+
*/
|
40 |
+
public function init_size_chart_tab( $tabs ) {
|
41 |
+
if ( strlen( $this->get_size_chart_content() ) > 0 ) {
|
42 |
+
$tabs['size_chart'] = array(
|
43 |
+
'title' => __( 'Size Chart', 'printful' ),
|
44 |
+
'priority' => 50,
|
45 |
+
'callback' => array( $this, 'size_chart_tab_content' ),
|
46 |
+
);
|
47 |
+
}
|
48 |
+
|
49 |
+
return $tabs;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Display the size chart content
|
54 |
+
*/
|
55 |
+
public function size_chart_tab_content() {
|
56 |
+
echo '<h2>' . esc_html__( 'Size Chart', 'printful' ) . '</h2>';
|
57 |
+
echo $this->get_size_chart_content();
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return mixed
|
62 |
+
*/
|
63 |
+
public function get_size_chart_content() {
|
64 |
+
global $post;
|
65 |
+
|
66 |
+
return htmlspecialchars_decode(get_post_meta( $post->ID, 'pf_size_chart', true ));
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @param $meta_id
|
71 |
+
*/
|
72 |
+
public function size_chart_metabox( $meta_id ) {
|
73 |
+
$settings = array(
|
74 |
+
'textarea_name' => 'pf_size_chart',
|
75 |
+
'tinymce' => array(
|
76 |
+
'theme_advanced_buttons1' => 'bold,italic,strikethrough,separator,bullist,numlist,separator,blockquote,separator,justifyleft,justifycenter,justifyright,separator,link,unlink,separator,undo,redo,separator',
|
77 |
+
'theme_advanced_buttons2' => '',
|
78 |
+
),
|
79 |
+
'editor_css' => '<style>#wp-pf_size_chart-editor-container .wp-editor-area{height:175px; width:100%;} .wp-editor-area{height:175px; width:100%;}</style>',
|
80 |
+
);
|
81 |
+
|
82 |
+
$content = get_post_meta( $meta_id->ID, 'pf_size_chart', true );
|
83 |
+
|
84 |
+
wp_editor( htmlspecialchars_decode( $content ), 'pf_size_chart_editor', apply_filters( 'woocommerce_product_short_description_editor_settings', $settings ) );
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param $post_id
|
89 |
+
* @param $post
|
90 |
+
*/
|
91 |
+
public function save_size_chart( $post_id, $post ) {
|
92 |
+
|
93 |
+
// $post_id and $post are required
|
94 |
+
if ( empty( $post_id ) || empty( $post ) || self::$saved_meta_boxes ) {
|
95 |
+
return;
|
96 |
+
}
|
97 |
+
|
98 |
+
// Dont' save meta boxes for revisions or autosaves
|
99 |
+
if ( defined( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
|
100 |
+
return;
|
101 |
+
}
|
102 |
+
|
103 |
+
// Check the nonce
|
104 |
+
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) {
|
105 |
+
return;
|
106 |
+
}
|
107 |
+
|
108 |
+
// Check the post being saved == the $post_id to prevent triggering this call for other save_post events
|
109 |
+
if ( empty( $_POST['post_ID'] ) || $_POST['post_ID'] != $post_id ) {
|
110 |
+
return;
|
111 |
+
}
|
112 |
+
|
113 |
+
// Check user has permission to edit
|
114 |
+
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
115 |
+
return;
|
116 |
+
}
|
117 |
+
|
118 |
+
// Check the post type
|
119 |
+
if ( $post->post_type != 'product' ) {
|
120 |
+
return;
|
121 |
+
}
|
122 |
+
|
123 |
+
// We need this save event to run once to avoid potential endless loops.
|
124 |
+
self::$saved_meta_boxes = true;
|
125 |
+
|
126 |
+
//save
|
127 |
+
update_post_meta($post_id, 'pf_size_chart', htmlspecialchars($_POST['pf_size_chart']));
|
128 |
+
}
|
129 |
}
|
includes/class-printful-size-guide.php
ADDED
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Printful_Size_Guide {
|
5 |
+
public static function init() {
|
6 |
+
$sizeGuide = new self();
|
7 |
+
|
8 |
+
$sizeGuide->hook_actions();
|
9 |
+
}
|
10 |
+
|
11 |
+
public function hook_actions() {
|
12 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'load_size_guide_scripts' ) );
|
13 |
+
}
|
14 |
+
|
15 |
+
public function load_size_guide_scripts() {
|
16 |
+
global $post;
|
17 |
+
|
18 |
+
$sizeGuideData = self::get_size_guide_for_product( $post );
|
19 |
+
if ( ! $sizeGuideData ) {
|
20 |
+
return;
|
21 |
+
}
|
22 |
+
|
23 |
+
$handle = 'printful-product-size-guide';
|
24 |
+
wp_enqueue_script( $handle, plugins_url( '../assets/js/product-size-guide.js', __FILE__ ) );
|
25 |
+
wp_localize_script(
|
26 |
+
$handle,
|
27 |
+
'pfGlobal',
|
28 |
+
array(
|
29 |
+
'sg_modal_title' => Printful_Integration::instance()
|
30 |
+
->get_option( 'pfsg_modal_title', Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_MODAL_TITLE ),
|
31 |
+
'sg_modal_text_color' => Printful_Integration::instance()
|
32 |
+
->get_option( 'pfsg_modal_text_color', Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_MODAL_TEXT_COLOR ),
|
33 |
+
'sg_modal_background_color' => Printful_Integration::instance()
|
34 |
+
->get_option(
|
35 |
+
'pfsg_modal_background_color',
|
36 |
+
Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_MODAL_BACKGROUND_COLOR
|
37 |
+
),
|
38 |
+
'sg_tab_background_color' => Printful_Integration::instance()
|
39 |
+
->get_option(
|
40 |
+
'pfsg_tab_background_color',
|
41 |
+
Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_TAB_BACKGROUND_COLOR
|
42 |
+
),
|
43 |
+
'sg_active_tab_background_color' => Printful_Integration::instance()
|
44 |
+
->get_option(
|
45 |
+
'pfsg_active_tab_background_color',
|
46 |
+
Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_ACTIVE_TAB_BACKGROUND_COLOR
|
47 |
+
),
|
48 |
+
'sg_primary_unit' => Printful_Integration::instance()
|
49 |
+
->get_option( 'pfsg_primary_unit', Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_UNIT ),
|
50 |
+
'sg_data_raw' => json_encode( $sizeGuideData ),
|
51 |
+
'sg_tab_title_person' => __( 'Measure yourself', 'printful' ),
|
52 |
+
'sg_tab_title_product' => __( 'Product measurements', 'printful' ),
|
53 |
+
)
|
54 |
+
);
|
55 |
+
wp_register_style( $handle, plugins_url( '../assets/css/size-guide.css', __FILE__ ) );
|
56 |
+
wp_enqueue_style( $handle );
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param WP_Post $product
|
61 |
+
*
|
62 |
+
* @return array|null
|
63 |
+
*/
|
64 |
+
public static function get_size_guide_for_product( $product = null ) {
|
65 |
+
if ( ! $product || ! get_post_meta( $product->ID, 'pf_advanced_size_chart', true ) ) {
|
66 |
+
return null;
|
67 |
+
}
|
68 |
+
|
69 |
+
// Size guide data should be a valid JSON
|
70 |
+
$size_guide_data = json_decode( get_post_meta( $product->ID, 'pf_advanced_size_chart', true ), true );
|
71 |
+
|
72 |
+
if ( ! self::is_size_guide_valid( $size_guide_data ) ) {
|
73 |
+
return null;
|
74 |
+
}
|
75 |
+
|
76 |
+
// URLs to size guide images
|
77 |
+
if ( isset( $size_guide_data['modelMeasurements']['imageId'] ) ) {
|
78 |
+
$size_guide_data['modelMeasurements']['imageUrl'] = self::get_attached_image_src( $size_guide_data['modelMeasurements']['imageId'] );
|
79 |
+
}
|
80 |
+
|
81 |
+
if ( isset( $size_guide_data['productMeasurements']['imageId'] ) ) {
|
82 |
+
$size_guide_data['productMeasurements']['imageUrl'] = self::get_attached_image_src( $size_guide_data['productMeasurements']['imageId'] );
|
83 |
+
}
|
84 |
+
|
85 |
+
return $size_guide_data;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param array $size_guide
|
90 |
+
*
|
91 |
+
* @return bool
|
92 |
+
*/
|
93 |
+
public static function is_size_guide_valid( $size_guide = null ) {
|
94 |
+
if ( empty( $size_guide ) || ! is_array( $size_guide ) ) {
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
// Size guide should have at least model or product measurement data
|
99 |
+
if ( ( empty( $size_guide['modelMeasurements'] ) && empty( $size_guide['productMeasurements'] ) )
|
100 |
+
|| empty( $size_guide['availableSizes'] ) ) {
|
101 |
+
return false;
|
102 |
+
}
|
103 |
+
|
104 |
+
// Validate size guide rows
|
105 |
+
$rows = [];
|
106 |
+
if ( ! empty( $size_guide['modelMeasurements']['sizeTableRows'] ) ) {
|
107 |
+
$rows += $size_guide['modelMeasurements']['sizeTableRows'];
|
108 |
+
}
|
109 |
+
|
110 |
+
if ( ! empty( $size_guide['productMeasurements']['sizeTableRows'] ) ) {
|
111 |
+
$rows += $size_guide['productMeasurements']['sizeTableRows'];
|
112 |
+
}
|
113 |
+
|
114 |
+
foreach ( $rows as $row ) {
|
115 |
+
if ( empty( $row['unit'] ) || empty( $row['sizes'] ) ) {
|
116 |
+
return false;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
return true;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param int $attachment_id
|
125 |
+
*
|
126 |
+
* @return string|null
|
127 |
+
*/
|
128 |
+
public static function get_attached_image_src( $attachment_id ) {
|
129 |
+
$attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
|
130 |
+
|
131 |
+
if ( ! is_array( $attachment ) ) {
|
132 |
+
return null;
|
133 |
+
}
|
134 |
+
|
135 |
+
return current( $attachment );
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Creates file from given url and stores as post attachment
|
140 |
+
*
|
141 |
+
* @param string $url
|
142 |
+
* @param string $file_name
|
143 |
+
*
|
144 |
+
* @return int|WP_Error
|
145 |
+
*/
|
146 |
+
public static function save_image( $url, $file_name ) {
|
147 |
+
if ( ! $url ) {
|
148 |
+
return null;
|
149 |
+
}
|
150 |
+
|
151 |
+
require_once ABSPATH . 'wp-admin/includes/file.php';
|
152 |
+
|
153 |
+
// Download size guide img to temp file
|
154 |
+
$temp_file_name = download_url( $url, 20 );
|
155 |
+
if ( is_wp_error( $temp_file_name ) ) {
|
156 |
+
return $temp_file_name;
|
157 |
+
}
|
158 |
+
|
159 |
+
// Validate image readability
|
160 |
+
require_once ABSPATH . 'wp-admin/includes/image.php';
|
161 |
+
if ( ! file_is_displayable_image( $temp_file_name ) ) {
|
162 |
+
@unlink( $temp_file_name );
|
163 |
+
|
164 |
+
return new WP_Error( 'pf_size_guide_img', 'Size guide attachment is not a valid image' );
|
165 |
+
}
|
166 |
+
|
167 |
+
$file_data = array(
|
168 |
+
'name' => $file_name,
|
169 |
+
'tmp_name' => $temp_file_name,
|
170 |
+
);
|
171 |
+
|
172 |
+
// Handle side load and attach to a post
|
173 |
+
require_once ABSPATH . 'wp-admin/includes/media.php';
|
174 |
+
$id = media_handle_sideload( $file_data );
|
175 |
+
|
176 |
+
@unlink( $temp_file_name );
|
177 |
+
|
178 |
+
if ( is_wp_error( $id ) ) {
|
179 |
+
return $id;
|
180 |
+
}
|
181 |
+
|
182 |
+
return $id;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* @param array $size_guide_data
|
187 |
+
* @param int $product_id
|
188 |
+
*
|
189 |
+
* @return array
|
190 |
+
*/
|
191 |
+
public static function process_size_guide_for_storage( $size_guide_data, $product_id ) {
|
192 |
+
$modelImageUrl = ! empty( $size_guide_data['modelMeasurements']['imageUrl'] )
|
193 |
+
? $size_guide_data['modelMeasurements']['imageUrl'] : null;
|
194 |
+
|
195 |
+
$productImageUrl = ! empty( $size_guide_data['productMeasurements']['imageUrl'] )
|
196 |
+
? $size_guide_data['productMeasurements']['imageUrl'] : null;
|
197 |
+
|
198 |
+
// Remove original URLs
|
199 |
+
unset( $size_guide_data['modelMeasurements']['imageUrl'] );
|
200 |
+
unset( $size_guide_data['productMeasurements']['imageUrl'] );
|
201 |
+
|
202 |
+
$modelImageId = self::save_image( $modelImageUrl, $product_id . '_model_size_guide.png' );
|
203 |
+
$productImageId = self::save_image( $productImageUrl, $product_id . '_product_size_guide.png' );
|
204 |
+
|
205 |
+
// Link size guide image attachments to size guide
|
206 |
+
$size_guide_data['modelMeasurements']['imageId'] = ! is_wp_error( $modelImageId ) ? $modelImageId : null;
|
207 |
+
$size_guide_data['productMeasurements']['imageId'] = ! is_wp_error( $productImageId ) ? $productImageId : null;
|
208 |
+
|
209 |
+
return $size_guide_data;
|
210 |
+
}
|
211 |
+
}
|
includes/class-printful-taxes.php
CHANGED
@@ -1,189 +1,189 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
-
|
4 |
-
class Printful_Taxes {
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Initialize the values, hooks and actions
|
8 |
-
*/
|
9 |
-
public static function init() {
|
10 |
-
if ( Printful_Integration::instance()->get_option( 'calculate_tax' ) == 'yes' ) {
|
11 |
-
//Update tax options if taxes are enabled
|
12 |
-
if ( get_option( 'woocommerce_calc_taxes' ) != 'yes' ) {
|
13 |
-
update_option( 'woocommerce_calc_taxes', 'yes' );
|
14 |
-
}
|
15 |
-
if ( get_option( 'woocommerce_tax_based_on' ) != 'shipping' ) {
|
16 |
-
update_option( 'woocommerce_tax_based_on', 'shipping' );
|
17 |
-
}
|
18 |
-
|
19 |
-
//Override tax rates calculated by Woocommerce
|
20 |
-
$taxes = new self;
|
21 |
-
add_filter( 'woocommerce_matched_tax_rates', array( $taxes, 'calculate_tax' ), 10, 6 );
|
22 |
-
}
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @param $matched_tax_rates
|
27 |
-
* @param $country
|
28 |
-
* @param $state
|
29 |
-
* @param $postcode
|
30 |
-
* @param $city
|
31 |
-
* @param $tax_class
|
32 |
-
*
|
33 |
-
* @return mixed
|
34 |
-
*/
|
35 |
-
public function calculate_tax( $matched_tax_rates, $country, $state, $postcode, $city, $tax_class ) {
|
36 |
-
//if a tax rate is already matched, avoid adding extra one
|
37 |
-
if ( ! empty( $matched_tax_rates ) ) {
|
38 |
-
return $matched_tax_rates;
|
39 |
-
}
|
40 |
-
|
41 |
-
$countries = $this->get_tax_countries();
|
42 |
-
if ( isset( $countries[ $country ][ $state ] ) && !empty($postcode) ) { //only make the request if country, state and zip are set
|
43 |
-
$key = 'printful_tax_rate_' . $country . '-' . $state . '-' . $city . '-' . $postcode;
|
44 |
-
$rate = get_transient( $key );
|
45 |
-
$response = null;
|
46 |
-
|
47 |
-
if ( $rate === false ) {
|
48 |
-
try {
|
49 |
-
$client = Printful_Integration::instance()->get_client();
|
50 |
-
$response = $client->post( 'tax/rates', array(
|
51 |
-
'recipient' => array(
|
52 |
-
'country_code' => $country,
|
53 |
-
'state_code' => $state,
|
54 |
-
'city' => $city,
|
55 |
-
'zip' => $postcode,
|
56 |
-
),
|
57 |
-
) );
|
58 |
-
} catch ( Exception $e ) {
|
59 |
-
}
|
60 |
-
|
61 |
-
if ( isset( $response['rate'] ) ) {
|
62 |
-
$rate = $response;
|
63 |
-
} else {
|
64 |
-
$rate = array(
|
65 |
-
'required' => false,
|
66 |
-
'rate' => 0,
|
67 |
-
'shipping_taxable' => false,
|
68 |
-
);
|
69 |
-
}
|
70 |
-
set_transient( $key, $rate, 1800 );
|
71 |
-
}
|
72 |
-
|
73 |
-
if ( $rate['required'] ) {
|
74 |
-
$rate_item = array(
|
75 |
-
'rate' => $rate['rate'] * 100,
|
76 |
-
'label' => 'Sales Tax',
|
77 |
-
'shipping' => $rate['shipping_taxable'] ? 'yes' : 'no',
|
78 |
-
'compound' => 'no',
|
79 |
-
);
|
80 |
-
|
81 |
-
if ( $this->isRateUnique( $rate_item, $matched_tax_rates ) ) {
|
82 |
-
$id = $this->get_printful_rate_id( $country, $state, $rate['shipping_taxable'] );
|
83 |
-
$matched_tax_rates[ $id ] = $rate_item;
|
84 |
-
}
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
return $matched_tax_rates;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Checks if a equal tax rate is not already set
|
93 |
-
*
|
94 |
-
* @param $rate
|
95 |
-
* @param $matched_tax_rates
|
96 |
-
*
|
97 |
-
* @return bool
|
98 |
-
*/
|
99 |
-
private function isRateUnique( $rate, $matched_tax_rates ) {
|
100 |
-
if ( empty( $matched_tax_rates ) ) {
|
101 |
-
return true;
|
102 |
-
}
|
103 |
-
|
104 |
-
foreach ( $matched_tax_rates as $mr ) {
|
105 |
-
if ( floatval( $mr['rate'] ) == floatval( $rate['rate'] ) && $mr['shipping'] == $rate['shipping'] ) {
|
106 |
-
return false;
|
107 |
-
}
|
108 |
-
}
|
109 |
-
|
110 |
-
return true;
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Gets list of countries and states where Printful needs to calculate sales tax
|
115 |
-
* @return array|mixed
|
116 |
-
*/
|
117 |
-
private function get_tax_countries() {
|
118 |
-
$countries = get_transient( 'printful_tax_countries' );
|
119 |
-
|
120 |
-
if ( ! $countries ) {
|
121 |
-
$countries = array();
|
122 |
-
|
123 |
-
try {
|
124 |
-
$client = Printful_Integration::instance()->get_client();
|
125 |
-
$list = $client->get( 'tax/countries' );
|
126 |
-
|
127 |
-
foreach ( $list as $country ) {
|
128 |
-
foreach ( $country['states'] as $state ) {
|
129 |
-
$countries[ $country['code'] ][ $state['code'] ] = 1;
|
130 |
-
}
|
131 |
-
}
|
132 |
-
|
133 |
-
if ( ! empty( $countries ) ) {
|
134 |
-
set_transient( 'printful_tax_countries', $countries, 6 * 3600 );
|
135 |
-
}
|
136 |
-
} catch ( Exception $e ) {
|
137 |
-
//Default to CA if can't get the actual state list
|
138 |
-
return array( 'US' => array( 'CA' => 1 ) );
|
139 |
-
}
|
140 |
-
}
|
141 |
-
|
142 |
-
return $countries;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* Creates dummy tax rate ID to display Printful tax rates in the cart summary.
|
147 |
-
*
|
148 |
-
* @param $cc
|
149 |
-
* @param $state
|
150 |
-
* @param bool $includeShipping
|
151 |
-
*
|
152 |
-
* @return int|null|string
|
153 |
-
*/
|
154 |
-
private function get_printful_rate_id( $cc, $state, $includeShipping = false ) {
|
155 |
-
global $wpdb;
|
156 |
-
|
157 |
-
$includeShipping = (int) $includeShipping;
|
158 |
-
|
159 |
-
$states = WC()->countries->get_states( $cc );
|
160 |
-
$tax_title = ( isset( $states[ $state ] ) ? $states[ $state ] . ' ' : '' ) . __( 'Sales Tax', 'printful' );
|
161 |
-
$id = $wpdb->get_var(
|
162 |
-
$wpdb->prepare( "SELECT tax_rate_id FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_class='printful'
|
163 |
-
and tax_rate_country = %s AND tax_rate_state = %s AND tax_rate_shipping = %s LIMIT 1",
|
164 |
-
$cc,
|
165 |
-
$state,
|
166 |
-
$includeShipping
|
167 |
-
) );
|
168 |
-
if ( empty( $id ) ) {
|
169 |
-
$wpdb->insert(
|
170 |
-
$wpdb->prefix . "woocommerce_tax_rates",
|
171 |
-
array(
|
172 |
-
'tax_rate_country' => $cc,
|
173 |
-
'tax_rate_state' => $state,
|
174 |
-
'tax_rate' => 0,
|
175 |
-
'tax_rate_name' => $tax_title,
|
176 |
-
'tax_rate_priority' => 1,
|
177 |
-
'tax_rate_compound' => 0,
|
178 |
-
'tax_rate_shipping' => $includeShipping,
|
179 |
-
'tax_rate_class' => 'printful',
|
180 |
-
)
|
181 |
-
);
|
182 |
-
$id = $wpdb->insert_id;
|
183 |
-
}
|
184 |
-
|
185 |
-
return $id;
|
186 |
-
}
|
187 |
-
|
188 |
-
|
189 |
}
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
class Printful_Taxes {
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Initialize the values, hooks and actions
|
8 |
+
*/
|
9 |
+
public static function init() {
|
10 |
+
if ( Printful_Integration::instance()->get_option( 'calculate_tax' ) == 'yes' ) {
|
11 |
+
//Update tax options if taxes are enabled
|
12 |
+
if ( get_option( 'woocommerce_calc_taxes' ) != 'yes' ) {
|
13 |
+
update_option( 'woocommerce_calc_taxes', 'yes' );
|
14 |
+
}
|
15 |
+
if ( get_option( 'woocommerce_tax_based_on' ) != 'shipping' ) {
|
16 |
+
update_option( 'woocommerce_tax_based_on', 'shipping' );
|
17 |
+
}
|
18 |
+
|
19 |
+
//Override tax rates calculated by Woocommerce
|
20 |
+
$taxes = new self;
|
21 |
+
add_filter( 'woocommerce_matched_tax_rates', array( $taxes, 'calculate_tax' ), 10, 6 );
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param $matched_tax_rates
|
27 |
+
* @param $country
|
28 |
+
* @param $state
|
29 |
+
* @param $postcode
|
30 |
+
* @param $city
|
31 |
+
* @param $tax_class
|
32 |
+
*
|
33 |
+
* @return mixed
|
34 |
+
*/
|
35 |
+
public function calculate_tax( $matched_tax_rates, $country, $state, $postcode, $city, $tax_class ) {
|
36 |
+
//if a tax rate is already matched, avoid adding extra one
|
37 |
+
if ( ! empty( $matched_tax_rates ) ) {
|
38 |
+
return $matched_tax_rates;
|
39 |
+
}
|
40 |
+
|
41 |
+
$countries = $this->get_tax_countries();
|
42 |
+
if ( isset( $countries[ $country ][ $state ] ) && !empty($postcode) ) { //only make the request if country, state and zip are set
|
43 |
+
$key = 'printful_tax_rate_' . $country . '-' . $state . '-' . $city . '-' . $postcode;
|
44 |
+
$rate = get_transient( $key );
|
45 |
+
$response = null;
|
46 |
+
|
47 |
+
if ( $rate === false ) {
|
48 |
+
try {
|
49 |
+
$client = Printful_Integration::instance()->get_client();
|
50 |
+
$response = $client->post( 'tax/rates', array(
|
51 |
+
'recipient' => array(
|
52 |
+
'country_code' => $country,
|
53 |
+
'state_code' => $state,
|
54 |
+
'city' => $city,
|
55 |
+
'zip' => $postcode,
|
56 |
+
),
|
57 |
+
) );
|
58 |
+
} catch ( Exception $e ) {
|
59 |
+
}
|
60 |
+
|
61 |
+
if ( isset( $response['rate'] ) ) {
|
62 |
+
$rate = $response;
|
63 |
+
} else {
|
64 |
+
$rate = array(
|
65 |
+
'required' => false,
|
66 |
+
'rate' => 0,
|
67 |
+
'shipping_taxable' => false,
|
68 |
+
);
|
69 |
+
}
|
70 |
+
set_transient( $key, $rate, 1800 );
|
71 |
+
}
|
72 |
+
|
73 |
+
if ( $rate['required'] ) {
|
74 |
+
$rate_item = array(
|
75 |
+
'rate' => $rate['rate'] * 100,
|
76 |
+
'label' => 'Sales Tax',
|
77 |
+
'shipping' => $rate['shipping_taxable'] ? 'yes' : 'no',
|
78 |
+
'compound' => 'no',
|
79 |
+
);
|
80 |
+
|
81 |
+
if ( $this->isRateUnique( $rate_item, $matched_tax_rates ) ) {
|
82 |
+
$id = $this->get_printful_rate_id( $country, $state, $rate['shipping_taxable'] );
|
83 |
+
$matched_tax_rates[ $id ] = $rate_item;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
return $matched_tax_rates;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Checks if a equal tax rate is not already set
|
93 |
+
*
|
94 |
+
* @param $rate
|
95 |
+
* @param $matched_tax_rates
|
96 |
+
*
|
97 |
+
* @return bool
|
98 |
+
*/
|
99 |
+
private function isRateUnique( $rate, $matched_tax_rates ) {
|
100 |
+
if ( empty( $matched_tax_rates ) ) {
|
101 |
+
return true;
|
102 |
+
}
|
103 |
+
|
104 |
+
foreach ( $matched_tax_rates as $mr ) {
|
105 |
+
if ( floatval( $mr['rate'] ) == floatval( $rate['rate'] ) && $mr['shipping'] == $rate['shipping'] ) {
|
106 |
+
return false;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
return true;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Gets list of countries and states where Printful needs to calculate sales tax
|
115 |
+
* @return array|mixed
|
116 |
+
*/
|
117 |
+
private function get_tax_countries() {
|
118 |
+
$countries = get_transient( 'printful_tax_countries' );
|
119 |
+
|
120 |
+
if ( ! $countries ) {
|
121 |
+
$countries = array();
|
122 |
+
|
123 |
+
try {
|
124 |
+
$client = Printful_Integration::instance()->get_client();
|
125 |
+
$list = $client->get( 'tax/countries' );
|
126 |
+
|
127 |
+
foreach ( $list as $country ) {
|
128 |
+
foreach ( $country['states'] as $state ) {
|
129 |
+
$countries[ $country['code'] ][ $state['code'] ] = 1;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
if ( ! empty( $countries ) ) {
|
134 |
+
set_transient( 'printful_tax_countries', $countries, 6 * 3600 );
|
135 |
+
}
|
136 |
+
} catch ( Exception $e ) {
|
137 |
+
//Default to CA if can't get the actual state list
|
138 |
+
return array( 'US' => array( 'CA' => 1 ) );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
return $countries;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Creates dummy tax rate ID to display Printful tax rates in the cart summary.
|
147 |
+
*
|
148 |
+
* @param $cc
|
149 |
+
* @param $state
|
150 |
+
* @param bool $includeShipping
|
151 |
+
*
|
152 |
+
* @return int|null|string
|
153 |
+
*/
|
154 |
+
private function get_printful_rate_id( $cc, $state, $includeShipping = false ) {
|
155 |
+
global $wpdb;
|
156 |
+
|
157 |
+
$includeShipping = (int) $includeShipping;
|
158 |
+
|
159 |
+
$states = WC()->countries->get_states( $cc );
|
160 |
+
$tax_title = ( isset( $states[ $state ] ) ? $states[ $state ] . ' ' : '' ) . __( 'Sales Tax', 'printful' );
|
161 |
+
$id = $wpdb->get_var(
|
162 |
+
$wpdb->prepare( "SELECT tax_rate_id FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_class='printful'
|
163 |
+
and tax_rate_country = %s AND tax_rate_state = %s AND tax_rate_shipping = %s LIMIT 1",
|
164 |
+
$cc,
|
165 |
+
$state,
|
166 |
+
$includeShipping
|
167 |
+
) );
|
168 |
+
if ( empty( $id ) ) {
|
169 |
+
$wpdb->insert(
|
170 |
+
$wpdb->prefix . "woocommerce_tax_rates",
|
171 |
+
array(
|
172 |
+
'tax_rate_country' => $cc,
|
173 |
+
'tax_rate_state' => $state,
|
174 |
+
'tax_rate' => 0,
|
175 |
+
'tax_rate_name' => $tax_title,
|
176 |
+
'tax_rate_priority' => 1,
|
177 |
+
'tax_rate_compound' => 0,
|
178 |
+
'tax_rate_shipping' => $includeShipping,
|
179 |
+
'tax_rate_class' => 'printful',
|
180 |
+
)
|
181 |
+
);
|
182 |
+
$id = $wpdb->insert_id;
|
183 |
+
}
|
184 |
+
|
185 |
+
return $id;
|
186 |
+
}
|
187 |
+
|
188 |
+
|
189 |
}
|
includes/class-printful-template.php
CHANGED
@@ -22,6 +22,8 @@ class Printful_Template {
|
|
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 |
/**
|
@@ -42,11 +44,34 @@ class Printful_Template {
|
|
42 |
}
|
43 |
}
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
/**
|
46 |
* Add hidden customizer hash ID field to form
|
47 |
*/
|
48 |
public static function printful_customizer_hash_field()
|
49 |
{
|
50 |
-
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
}
|
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 |
+
// Hook size guide button
|
26 |
+
add_action( 'woocommerce_before_single_variation', array( $this, 'printful_size_guide_button' ), 20 );
|
27 |
}
|
28 |
|
29 |
/**
|
44 |
}
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* Hook callback for size guide button render within product page
|
49 |
+
*/
|
50 |
+
public static function printful_size_guide_button()
|
51 |
+
{
|
52 |
+
global $post;
|
53 |
+
|
54 |
+
$sizeGuideData = Printful_Size_Guide::get_size_guide_for_product($post);
|
55 |
+
if (!$sizeGuideData) {
|
56 |
+
return;
|
57 |
+
}
|
58 |
+
|
59 |
+
// Load size guide button template
|
60 |
+
Printful_Admin::load_template( 'size-guide-button', array(
|
61 |
+
'size_guide_button_color' => Printful_Integration::instance()->get_option( 'pfsg_button_color' ) ?: Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_BUTTON_COLOR,
|
62 |
+
'size_guide_button_text' => Printful_Integration::instance()->get_option( 'pfsg_button_text' ) ?: Printful_Admin_Settings::DEFAULT_SIZE_GUIDE_BUTTON_TEXT,
|
63 |
+
) );
|
64 |
+
}
|
65 |
+
|
66 |
/**
|
67 |
* Add hidden customizer hash ID field to form
|
68 |
*/
|
69 |
public static function printful_customizer_hash_field()
|
70 |
{
|
71 |
+
global $post;
|
72 |
+
|
73 |
+
if ( $post && get_post_meta( $post->ID, 'pf_customizable', true ) ) {
|
74 |
+
Printful_Admin::load_template('customizer-hidden-input');
|
75 |
+
}
|
76 |
}
|
77 |
}
|
includes/templates/ajax-loader.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
<div id="loader-block-<?php echo esc_attr($action); ?>">
|
2 |
-
<div class="block-loader loader-wrap">
|
3 |
-
<img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ) ?>" class="loader" width="20px" height="20px" alt="loader"/>
|
4 |
-
<span class="message"><?php echo esc_html($message); ?></span>
|
5 |
-
</div>
|
6 |
-
</div>
|
7 |
-
<script type="text/javascript">
|
8 |
-
jQuery(document).ready(function () {
|
9 |
-
Printful_Block_Loader.load('<?php echo esc_url(admin_url( 'admin-ajax.php?action=' . $action )); ?>', 'loader-block-<?php echo esc_attr($action); ?>');
|
10 |
-
});
|
11 |
</script>
|
1 |
+
<div id="loader-block-<?php echo esc_attr($action); ?>">
|
2 |
+
<div class="block-loader loader-wrap">
|
3 |
+
<img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ) ?>" class="loader" width="20px" height="20px" alt="loader"/>
|
4 |
+
<span class="message"><?php echo esc_html($message); ?></span>
|
5 |
+
</div>
|
6 |
+
</div>
|
7 |
+
<script type="text/javascript">
|
8 |
+
jQuery(document).ready(function () {
|
9 |
+
Printful_Block_Loader.load('<?php echo esc_url(admin_url( 'admin-ajax.php?action=' . $action )); ?>', 'loader-block-<?php echo esc_attr($action); ?>');
|
10 |
+
});
|
11 |
</script>
|
includes/templates/connect.php
CHANGED
@@ -1,40 +1,40 @@
|
|
1 |
-
<div class="printful-connect">
|
2 |
-
|
3 |
-
<div class="printful-connect-inner">
|
4 |
-
|
5 |
-
<h1><?php esc_html_e('Connect to Printful', 'printful'); ?></h1>
|
6 |
-
|
7 |
-
<img src=" <?php echo esc_url(Printful_Base::get_asset_url() . 'images/connect.svg'); ?>" class="connect-image" alt="connect to printful">
|
8 |
-
|
9 |
-
<?php
|
10 |
-
if ( ! empty( $issues ) ) {
|
11 |
-
?>
|
12 |
-
<p><?php esc_html_e('To connect your store to Printful, fix the following errors:', 'printful'); ?></p>
|
13 |
-
<div class="printful-notice">
|
14 |
-
<ul>
|
15 |
-
<?php
|
16 |
-
foreach ( $issues as $issue ) {
|
17 |
-
echo '<li>' . wp_kses_post( $issue ) . '</li>';
|
18 |
-
}
|
19 |
-
?>
|
20 |
-
</ul>
|
21 |
-
</div>
|
22 |
-
<?php
|
23 |
-
$url = '#';
|
24 |
-
} else {
|
25 |
-
?><p class="connect-description"><?php esc_html_e('You\'re almost done! Just 2 more steps to have your WooCommerce store connected to Printful for automatic order fulfillment.', 'printful'); ?></p><?php
|
26 |
-
$url = Printful_Base::get_printful_host() . 'dashboard/woocommerce/plugin-connect?website=' . urlencode( trailingslashit( get_home_url() ) ) . '&key=' . urlencode( $consumer_key ) . '&returnUrl=' . urlencode( get_admin_url( null,'admin.php?page=' . Printful_Admin::MENU_SLUG_DASHBOARD ) );
|
27 |
-
}
|
28 |
-
|
29 |
-
echo '<a href="' . esc_url($url) . '" class="button button-primary printful-connect-button ' . ( ! empty( $issues ) ? 'disabled' : '' ) . '" target="_blank">' . esc_html__('Connect', 'printful') . '</a>';
|
30 |
-
?>
|
31 |
-
|
32 |
-
<img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ) ?>" class="loader hidden" width="20px" height="20px" alt="loader"/>
|
33 |
-
|
34 |
-
<script type="text/javascript">
|
35 |
-
jQuery(document).ready(function () {
|
36 |
-
Printful_Connect.init('<?php echo esc_url( admin_url( 'admin-ajax.php?action=ajax_force_check_connect_status' ) ); ?>');
|
37 |
-
});
|
38 |
-
</script>
|
39 |
-
</div>
|
40 |
</div>
|
1 |
+
<div class="printful-connect">
|
2 |
+
|
3 |
+
<div class="printful-connect-inner">
|
4 |
+
|
5 |
+
<h1><?php esc_html_e('Connect to Printful', 'printful'); ?></h1>
|
6 |
+
|
7 |
+
<img src=" <?php echo esc_url(Printful_Base::get_asset_url() . 'images/connect.svg'); ?>" class="connect-image" alt="connect to printful">
|
8 |
+
|
9 |
+
<?php
|
10 |
+
if ( ! empty( $issues ) ) {
|
11 |
+
?>
|
12 |
+
<p><?php esc_html_e('To connect your store to Printful, fix the following errors:', 'printful'); ?></p>
|
13 |
+
<div class="printful-notice">
|
14 |
+
<ul>
|
15 |
+
<?php
|
16 |
+
foreach ( $issues as $issue ) {
|
17 |
+
echo '<li>' . wp_kses_post( $issue ) . '</li>';
|
18 |
+
}
|
19 |
+
?>
|
20 |
+
</ul>
|
21 |
+
</div>
|
22 |
+
<?php
|
23 |
+
$url = '#';
|
24 |
+
} else {
|
25 |
+
?><p class="connect-description"><?php esc_html_e('You\'re almost done! Just 2 more steps to have your WooCommerce store connected to Printful for automatic order fulfillment.', 'printful'); ?></p><?php
|
26 |
+
$url = Printful_Base::get_printful_host() . 'dashboard/woocommerce/plugin-connect?website=' . urlencode( trailingslashit( get_home_url() ) ) . '&key=' . urlencode( $consumer_key ) . '&returnUrl=' . urlencode( get_admin_url( null,'admin.php?page=' . Printful_Admin::MENU_SLUG_DASHBOARD ) );
|
27 |
+
}
|
28 |
+
|
29 |
+
echo '<a href="' . esc_url($url) . '" class="button button-primary printful-connect-button ' . ( ! empty( $issues ) ? 'disabled' : '' ) . '" target="_blank">' . esc_html__('Connect', 'printful') . '</a>';
|
30 |
+
?>
|
31 |
+
|
32 |
+
<img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ) ?>" class="loader hidden" width="20px" height="20px" alt="loader"/>
|
33 |
+
|
34 |
+
<script type="text/javascript">
|
35 |
+
jQuery(document).ready(function () {
|
36 |
+
Printful_Connect.init('<?php echo esc_url( admin_url( 'admin-ajax.php?action=ajax_force_check_connect_status' ) ); ?>');
|
37 |
+
});
|
38 |
+
</script>
|
39 |
+
</div>
|
40 |
</div>
|
includes/templates/header.php
CHANGED
@@ -1,20 +1,20 @@
|
|
1 |
-
<div class="wrap">
|
2 |
-
|
3 |
-
<?php
|
4 |
-
$base_url = '?page=printful-dashboard';
|
5 |
-
?>
|
6 |
-
|
7 |
-
<h2 class="nav-tab-wrapper printful-tabs">
|
8 |
-
<?php foreach ($tabs as $tab) : ?>
|
9 |
-
<?php
|
10 |
-
$active = '';
|
11 |
-
if ( ! empty( $_GET['tab'] ) && $_GET['tab'] == $tab['tab_url'] ) {
|
12 |
-
$active = 'nav-tab-active';
|
13 |
-
}
|
14 |
-
if ( empty( $_GET['tab'] ) && $tab['tab_url'] == '' ) {
|
15 |
-
$active = 'nav-tab-active';
|
16 |
-
}
|
17 |
-
?>
|
18 |
-
<a href="<?php echo esc_url($base_url . ($tab['tab_url'] ? '&tab=' . $tab['tab_url'] : '') ); ?>" class="nav-tab <?php echo esc_attr($active);?>"><?php echo esc_html($tab['name']); ?></a>
|
19 |
-
<?php endforeach; ?>
|
20 |
</h2>
|
1 |
+
<div class="wrap">
|
2 |
+
|
3 |
+
<?php
|
4 |
+
$base_url = '?page=printful-dashboard';
|
5 |
+
?>
|
6 |
+
|
7 |
+
<h2 class="nav-tab-wrapper printful-tabs">
|
8 |
+
<?php foreach ($tabs as $tab) : ?>
|
9 |
+
<?php
|
10 |
+
$active = '';
|
11 |
+
if ( ! empty( $_GET['tab'] ) && $_GET['tab'] == $tab['tab_url'] ) {
|
12 |
+
$active = 'nav-tab-active';
|
13 |
+
}
|
14 |
+
if ( empty( $_GET['tab'] ) && $tab['tab_url'] == '' ) {
|
15 |
+
$active = 'nav-tab-active';
|
16 |
+
}
|
17 |
+
?>
|
18 |
+
<a href="<?php echo esc_url($base_url . ($tab['tab_url'] ? '&tab=' . $tab['tab_url'] : '') ); ?>" class="nav-tab <?php echo esc_attr($active);?>"><?php echo esc_html($tab['name']); ?></a>
|
19 |
+
<?php endforeach; ?>
|
20 |
</h2>
|
includes/templates/inline-script.php
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<script type="text/javascript">
|
2 |
-
<?php echo esc_js( $script ); ?>
|
3 |
</script>
|
1 |
+
<script type="text/javascript">
|
2 |
+
<?php echo esc_js( $script ); ?>
|
3 |
</script>
|
includes/templates/order-table.php
CHANGED
@@ -1,69 +1,69 @@
|
|
1 |
-
|
2 |
-
<h2>Printful product orders</h2>
|
3 |
-
|
4 |
-
<?php if ( ! empty( $orders ) && $orders['count'] > 0 ): ?>
|
5 |
-
|
6 |
-
<table class="wp-list-table widefat fixed striped printful-latest-orders">
|
7 |
-
<thead>
|
8 |
-
<tr>
|
9 |
-
<th class="col-order"><?php esc_html_e('Order', 'printful'); ?></th>
|
10 |
-
<th class="col-date"><?php esc_html_e('Date', 'printful'); ?></th>
|
11 |
-
<th class="col-from"><?php esc_html_e('From', 'printful'); ?></th>
|
12 |
-
<th class="col-status"><?php esc_html_e('Status', 'printful'); ?></th>
|
13 |
-
<th class="col-total"><?php esc_html_e('Total', 'printful'); ?></th>
|
14 |
-
<th class="col-actions"><?php esc_html_e('Actions', 'printful'); ?></th>
|
15 |
-
</tr>
|
16 |
-
</thead>
|
17 |
-
<tbody>
|
18 |
-
|
19 |
-
<?php foreach ( $orders['results'] as $order ) : ?>
|
20 |
-
|
21 |
-
<tr>
|
22 |
-
<td>
|
23 |
-
<?php
|
24 |
-
if ( $order['external_id'] ) {
|
25 |
-
echo '<a href="' . esc_url( get_edit_post_link( $order['external_id'] ) ) . '">';
|
26 |
-
echo '#' . esc_html( $order['external_id'] );
|
27 |
-
echo '</a>';
|
28 |
-
} else {
|
29 |
-
echo '#' . esc_html( $order['id'] );
|
30 |
-
}
|
31 |
-
?>
|
32 |
-
</td>
|
33 |
-
<td>
|
34 |
-
<?php echo esc_html( date('Y-m-d', $order['created']) ); ?>
|
35 |
-
</td>
|
36 |
-
<td>
|
37 |
-
<?php echo esc_html( $order['recipient']['name'] ); ?>
|
38 |
-
</td>
|
39 |
-
<td>
|
40 |
-
<?php echo esc_html( ucfirst($order['status']) ); ?>
|
41 |
-
</td>
|
42 |
-
<td>
|
43 |
-
$<?php echo esc_html( $order['costs']['total'] ); ?>
|
44 |
-
</td>
|
45 |
-
<td>
|
46 |
-
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>dashboard?order_id=<?php echo esc_attr($order['id']); ?>" target="_blank"><?php esc_html_e('Open in Printful', 'printful'); ?></a>
|
47 |
-
</td>
|
48 |
-
</tr>
|
49 |
-
|
50 |
-
<?php endforeach; ?>
|
51 |
-
|
52 |
-
</tbody>
|
53 |
-
<tfoot>
|
54 |
-
<tr>
|
55 |
-
<th class="col-order"><?php esc_html_e('Order', 'printful'); ?></th>
|
56 |
-
<th class="col-date"><?php esc_html_e('Date', 'printful'); ?></th>
|
57 |
-
<th class="col-from"><?php esc_html_e('From', 'printful'); ?></th>
|
58 |
-
<th class="col-status"><?php esc_html_e('Status', 'printful'); ?></th>
|
59 |
-
<th class="col-total"><?php esc_html_e('Total', 'printful'); ?></th>
|
60 |
-
<th class="col-actions"><?php esc_html_e('Actions', 'printful'); ?></th>
|
61 |
-
</tr>
|
62 |
-
</tfoot>
|
63 |
-
</table>
|
64 |
-
|
65 |
-
<?php else: ?>
|
66 |
-
<div class="printful-latest-orders">
|
67 |
-
<p><?php esc_html_e('Once your store gets some Printful product orders, they will be shown here!', 'printful'); ?></p>
|
68 |
-
</div>
|
69 |
<?php endif; ?>
|
1 |
+
|
2 |
+
<h2>Printful product orders</h2>
|
3 |
+
|
4 |
+
<?php if ( ! empty( $orders ) && $orders['count'] > 0 ): ?>
|
5 |
+
|
6 |
+
<table class="wp-list-table widefat fixed striped printful-latest-orders">
|
7 |
+
<thead>
|
8 |
+
<tr>
|
9 |
+
<th class="col-order"><?php esc_html_e('Order', 'printful'); ?></th>
|
10 |
+
<th class="col-date"><?php esc_html_e('Date', 'printful'); ?></th>
|
11 |
+
<th class="col-from"><?php esc_html_e('From', 'printful'); ?></th>
|
12 |
+
<th class="col-status"><?php esc_html_e('Status', 'printful'); ?></th>
|
13 |
+
<th class="col-total"><?php esc_html_e('Total', 'printful'); ?></th>
|
14 |
+
<th class="col-actions"><?php esc_html_e('Actions', 'printful'); ?></th>
|
15 |
+
</tr>
|
16 |
+
</thead>
|
17 |
+
<tbody>
|
18 |
+
|
19 |
+
<?php foreach ( $orders['results'] as $order ) : ?>
|
20 |
+
|
21 |
+
<tr>
|
22 |
+
<td>
|
23 |
+
<?php
|
24 |
+
if ( $order['external_id'] ) {
|
25 |
+
echo '<a href="' . esc_url( get_edit_post_link( $order['external_id'] ) ) . '">';
|
26 |
+
echo '#' . esc_html( $order['external_id'] );
|
27 |
+
echo '</a>';
|
28 |
+
} else {
|
29 |
+
echo '#' . esc_html( $order['id'] );
|
30 |
+
}
|
31 |
+
?>
|
32 |
+
</td>
|
33 |
+
<td>
|
34 |
+
<?php echo esc_html( date('Y-m-d', $order['created']) ); ?>
|
35 |
+
</td>
|
36 |
+
<td>
|
37 |
+
<?php echo esc_html( $order['recipient']['name'] ); ?>
|
38 |
+
</td>
|
39 |
+
<td>
|
40 |
+
<?php echo esc_html( ucfirst($order['status']) ); ?>
|
41 |
+
</td>
|
42 |
+
<td>
|
43 |
+
$<?php echo esc_html( $order['costs']['total'] ); ?>
|
44 |
+
</td>
|
45 |
+
<td>
|
46 |
+
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>dashboard?order_id=<?php echo esc_attr($order['id']); ?>" target="_blank"><?php esc_html_e('Open in Printful', 'printful'); ?></a>
|
47 |
+
</td>
|
48 |
+
</tr>
|
49 |
+
|
50 |
+
<?php endforeach; ?>
|
51 |
+
|
52 |
+
</tbody>
|
53 |
+
<tfoot>
|
54 |
+
<tr>
|
55 |
+
<th class="col-order"><?php esc_html_e('Order', 'printful'); ?></th>
|
56 |
+
<th class="col-date"><?php esc_html_e('Date', 'printful'); ?></th>
|
57 |
+
<th class="col-from"><?php esc_html_e('From', 'printful'); ?></th>
|
58 |
+
<th class="col-status"><?php esc_html_e('Status', 'printful'); ?></th>
|
59 |
+
<th class="col-total"><?php esc_html_e('Total', 'printful'); ?></th>
|
60 |
+
<th class="col-actions"><?php esc_html_e('Actions', 'printful'); ?></th>
|
61 |
+
</tr>
|
62 |
+
</tfoot>
|
63 |
+
</table>
|
64 |
+
|
65 |
+
<?php else: ?>
|
66 |
+
<div class="printful-latest-orders">
|
67 |
+
<p><?php esc_html_e('Once your store gets some Printful product orders, they will be shown here!', 'printful'); ?></p>
|
68 |
+
</div>
|
69 |
<?php endif; ?>
|
includes/templates/personalize-button.php
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @var string $pfc_button_color
|
4 |
-
* @var string $site_url
|
5 |
-
* @var string $pfc_button_text
|
6 |
-
*/
|
7 |
-
?>
|
8 |
-
<a class="button"
|
9 |
-
style="background-color: <?php esc_attr_e($pfc_button_color); ?>"
|
10 |
-
onclick="Printful_Product_Customizer.onCustomizeClick( '<?php echo esc_url($site_url); ?>')">
|
11 |
-
<?php esc_html_e($pfc_button_text, 'printful'); ?>
|
12 |
</a>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var string $pfc_button_color
|
4 |
+
* @var string $site_url
|
5 |
+
* @var string $pfc_button_text
|
6 |
+
*/
|
7 |
+
?>
|
8 |
+
<a class="button"
|
9 |
+
style="background-color: <?php esc_attr_e($pfc_button_color); ?>"
|
10 |
+
onclick="Printful_Product_Customizer.onCustomizeClick( '<?php echo esc_url($site_url); ?>')">
|
11 |
+
<?php esc_html_e($pfc_button_text, 'printful'); ?>
|
12 |
</a>
|
includes/templates/setting-group.php
CHANGED
@@ -73,7 +73,18 @@
|
|
73 |
|
74 |
<?php elseif ($setting['type'] == 'color-picker') : ?>
|
75 |
<label for="<?php esc_attr_e($key); ?>">
|
76 |
-
<input type="text" name="<?php esc_attr_e($key); ?>" class="<?php esc_attr_e($key); ?>" value="<?php esc_attr_e($setting['value'] ?: $setting['default']); ?>" data-default-color="<?php esc_attr_e($setting['default']); ?>" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
<?php endif; ?>
|
78 |
|
79 |
</fieldset>
|
@@ -89,6 +100,6 @@
|
|
89 |
</div>
|
90 |
<script>
|
91 |
jQuery(document).ready(function($){
|
92 |
-
$('.
|
93 |
});
|
94 |
</script>
|
73 |
|
74 |
<?php elseif ($setting['type'] == 'color-picker') : ?>
|
75 |
<label for="<?php esc_attr_e($key); ?>">
|
76 |
+
<input type="text" name="<?php esc_attr_e($key); ?>" class="<?php esc_attr_e($key); ?> pf-color-picker" value="<?php esc_attr_e($setting['value'] ?: $setting['default']); ?>" data-default-color="<?php esc_attr_e($setting['default']); ?>" />
|
77 |
+
|
78 |
+
<?php elseif ($setting['type'] == 'dropdown') : ?>
|
79 |
+
<label for="<?php esc_attr_e($key); ?>">
|
80 |
+
<select name="<?php esc_attr_e($key); ?>" id="<?php esc_attr_e($key); ?>">
|
81 |
+
<?php foreach ( $setting['items'] as $selectionKey => $selectionValue ) : ?>
|
82 |
+
<option <?php echo $setting['selected'] === $selectionKey ? 'selected' : ''; ?>
|
83 |
+
value="<?php esc_attr_e($selectionKey); ?>">
|
84 |
+
<?php esc_attr_e($selectionValue); ?>
|
85 |
+
</option>
|
86 |
+
<?php endforeach; ?>
|
87 |
+
</select>
|
88 |
<?php endif; ?>
|
89 |
|
90 |
</fieldset>
|
100 |
</div>
|
101 |
<script>
|
102 |
jQuery(document).ready(function($){
|
103 |
+
$('.pf-color-picker').wpColorPicker();
|
104 |
});
|
105 |
</script>
|
includes/templates/setting-submit.php
CHANGED
@@ -1,24 +1,24 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @var bool $disabled
|
4 |
-
*/
|
5 |
-
?>
|
6 |
-
<p class="printful-submit">
|
7 |
-
<input name="save" class="button-primary woocommerce-save-button <?php if($disabled) { echo 'disabled'; } ?>" type="submit" value="<?php esc_attr_e('Save changes', 'printful'); ?>" <?php if($disabled) { echo 'disabled'; } ?>/>
|
8 |
-
<input type="hidden" id="_wpnonce" name="_wpnonce" value="<?php echo esc_attr($nonce); ?>">
|
9 |
-
<?php wp_referer_field(true); ?>
|
10 |
-
<span class="loader-wrap">
|
11 |
-
<img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ) ?>" class="loader" width="20px" height="20px" alt="loader"/>
|
12 |
-
<span class="pass">
|
13 |
-
<span class="dashicons dashicons-yes"></span>
|
14 |
-
<?php esc_html_e('Saved successfully', 'printful'); ?>
|
15 |
-
</span>
|
16 |
-
<span class="fail">
|
17 |
-
</span>
|
18 |
-
</span>
|
19 |
-
</p>
|
20 |
-
<script type="text/javascript">
|
21 |
-
jQuery(document).ready(function () {
|
22 |
-
Printful_Settings.init_submit();
|
23 |
-
});
|
24 |
</script>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var bool $disabled
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<p class="printful-submit">
|
7 |
+
<input name="save" class="button-primary woocommerce-save-button <?php if($disabled) { echo 'disabled'; } ?>" type="submit" value="<?php esc_attr_e('Save changes', 'printful'); ?>" <?php if($disabled) { echo 'disabled'; } ?>/>
|
8 |
+
<input type="hidden" id="_wpnonce" name="_wpnonce" value="<?php echo esc_attr($nonce); ?>">
|
9 |
+
<?php wp_referer_field(true); ?>
|
10 |
+
<span class="loader-wrap">
|
11 |
+
<img src="<?php echo esc_url( admin_url( 'images/spinner-2x.gif' ) ) ?>" class="loader" width="20px" height="20px" alt="loader"/>
|
12 |
+
<span class="pass">
|
13 |
+
<span class="dashicons dashicons-yes"></span>
|
14 |
+
<?php esc_html_e('Saved successfully', 'printful'); ?>
|
15 |
+
</span>
|
16 |
+
<span class="fail">
|
17 |
+
</span>
|
18 |
+
</span>
|
19 |
+
</p>
|
20 |
+
<script type="text/javascript">
|
21 |
+
jQuery(document).ready(function () {
|
22 |
+
Printful_Settings.init_submit();
|
23 |
+
});
|
24 |
</script>
|
includes/templates/shipping-notification.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="printful-setting-group">
|
2 |
-
<h2><?php esc_html_e('Printful Shipping', 'printful'); ?></h2>
|
3 |
-
<p><?php esc_html_e('To enable/disable Printful shipping for your store go to', 'printful'); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=printful_shipping' ) ); ?>"><?php esc_html_e('WooCommerce Shipping settings', 'printful'); ?></a>.</p>
|
4 |
</div>
|
1 |
+
<div class="printful-setting-group">
|
2 |
+
<h2><?php esc_html_e('Printful Shipping', 'printful'); ?></h2>
|
3 |
+
<p><?php esc_html_e('To enable/disable Printful shipping for your store go to', 'printful'); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=printful_shipping' ) ); ?>"><?php esc_html_e('WooCommerce Shipping settings', 'printful'); ?></a>.</p>
|
4 |
</div>
|
includes/templates/size-guide-button.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var string $size_guide_button_color
|
4 |
+
* @var string $size_guide_button_text
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<a href="javascript:" style="color: <?php esc_attr_e($size_guide_button_color); ?>"
|
8 |
+
onclick="Printful_Product_Size_Guide.onSizeGuideClick()">
|
9 |
+
<?php esc_html_e($size_guide_button_text, 'printful'); ?>
|
10 |
+
</a>
|
includes/templates/stats.php
CHANGED
@@ -1,44 +1,44 @@
|
|
1 |
-
<div class="printful-stats">
|
2 |
-
<div class="printful-stats-item">
|
3 |
-
<h4><?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_html($stats['orders_today']['total']); ?></h4>
|
4 |
-
<b>
|
5 |
-
<?php
|
6 |
-
echo esc_html($stats['orders_today']['orders']);
|
7 |
-
echo ' ' . _n('ORDER', 'ORDERS', $stats['orders_today']['orders'], 'printful' );
|
8 |
-
?>
|
9 |
-
</b>
|
10 |
-
<?php esc_html_e('today', 'printful'); ?>
|
11 |
-
</div>
|
12 |
-
<div class="printful-stats-item">
|
13 |
-
<h4>
|
14 |
-
<?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_html($stats['orders_last_7_days']['total']); ?>
|
15 |
-
<?php echo '<span class="dashicons dashicons-arrow-' . esc_attr($stats['orders_last_7_days']['trend']) .'-alt"></span>'; ?>
|
16 |
-
</h4>
|
17 |
-
<b>
|
18 |
-
<?php
|
19 |
-
echo esc_html($stats['orders_last_7_days']['orders']);
|
20 |
-
echo ' ' . _n( 'ORDER', 'ORDERS', $stats['orders_last_7_days']['orders'], 'printful' );
|
21 |
-
?>
|
22 |
-
</b>
|
23 |
-
<?php esc_html_e('last 7 days', 'printful'); ?>
|
24 |
-
</div>
|
25 |
-
<div class="printful-stats-item">
|
26 |
-
<h4>
|
27 |
-
<?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_html($stats['orders_last_28_days']['total']); ?>
|
28 |
-
<?php echo '<span class="dashicons dashicons-arrow-' . esc_attr($stats['orders_last_28_days']['trend']) .'-alt"></span>'; ?>
|
29 |
-
</h4>
|
30 |
-
<b>
|
31 |
-
<?php
|
32 |
-
echo esc_html($stats['orders_last_28_days']['orders']);
|
33 |
-
echo ' ' . _n( 'ORDER', 'ORDERS', $stats['orders_last_28_days']['orders'], 'printful' );
|
34 |
-
?>
|
35 |
-
</b> <?php esc_html_e('last 28 days', 'printful'); ?>
|
36 |
-
</div>
|
37 |
-
<div class="printful-stats-item">
|
38 |
-
<h4>
|
39 |
-
<?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_attr($stats['profit_last_28_days']); ?>
|
40 |
-
<?php echo '<span class="dashicons dashicons-arrow-' . esc_attr($stats['profit_trend_last_28_days']) .'-alt"></span>'; ?>
|
41 |
-
</h4>
|
42 |
-
<b><?php esc_html_e('PROFIT', 'printful'); ?></b> <?php esc_html_e('last 28 days', 'printful'); ?>
|
43 |
-
</div>
|
44 |
</div>
|
1 |
+
<div class="printful-stats">
|
2 |
+
<div class="printful-stats-item">
|
3 |
+
<h4><?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_html($stats['orders_today']['total']); ?></h4>
|
4 |
+
<b>
|
5 |
+
<?php
|
6 |
+
echo esc_html($stats['orders_today']['orders']);
|
7 |
+
echo ' ' . _n('ORDER', 'ORDERS', $stats['orders_today']['orders'], 'printful' );
|
8 |
+
?>
|
9 |
+
</b>
|
10 |
+
<?php esc_html_e('today', 'printful'); ?>
|
11 |
+
</div>
|
12 |
+
<div class="printful-stats-item">
|
13 |
+
<h4>
|
14 |
+
<?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_html($stats['orders_last_7_days']['total']); ?>
|
15 |
+
<?php echo '<span class="dashicons dashicons-arrow-' . esc_attr($stats['orders_last_7_days']['trend']) .'-alt"></span>'; ?>
|
16 |
+
</h4>
|
17 |
+
<b>
|
18 |
+
<?php
|
19 |
+
echo esc_html($stats['orders_last_7_days']['orders']);
|
20 |
+
echo ' ' . _n( 'ORDER', 'ORDERS', $stats['orders_last_7_days']['orders'], 'printful' );
|
21 |
+
?>
|
22 |
+
</b>
|
23 |
+
<?php esc_html_e('last 7 days', 'printful'); ?>
|
24 |
+
</div>
|
25 |
+
<div class="printful-stats-item">
|
26 |
+
<h4>
|
27 |
+
<?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_html($stats['orders_last_28_days']['total']); ?>
|
28 |
+
<?php echo '<span class="dashicons dashicons-arrow-' . esc_attr($stats['orders_last_28_days']['trend']) .'-alt"></span>'; ?>
|
29 |
+
</h4>
|
30 |
+
<b>
|
31 |
+
<?php
|
32 |
+
echo esc_html($stats['orders_last_28_days']['orders']);
|
33 |
+
echo ' ' . _n( 'ORDER', 'ORDERS', $stats['orders_last_28_days']['orders'], 'printful' );
|
34 |
+
?>
|
35 |
+
</b> <?php esc_html_e('last 28 days', 'printful'); ?>
|
36 |
+
</div>
|
37 |
+
<div class="printful-stats-item">
|
38 |
+
<h4>
|
39 |
+
<?php echo esc_html(get_woocommerce_currency_symbol($stats['currency'])) . ' ' . esc_attr($stats['profit_last_28_days']); ?>
|
40 |
+
<?php echo '<span class="dashicons dashicons-arrow-' . esc_attr($stats['profit_trend_last_28_days']) .'-alt"></span>'; ?>
|
41 |
+
</h4>
|
42 |
+
<b><?php esc_html_e('PROFIT', 'printful'); ?></b> <?php esc_html_e('last 28 days', 'printful'); ?>
|
43 |
+
</div>
|
44 |
</div>
|
includes/templates/status-report.php
CHANGED
@@ -1,23 +1,23 @@
|
|
1 |
-
<div class="support-report-wrap">
|
2 |
-
<p>
|
3 |
-
<?php esc_html_e('Copy the box content below and add it to your support message', 'printful'); ?>
|
4 |
-
<br/>
|
5 |
-
<?php esc_html_e('Note: this status report may not include an error log. Contact your hosting provider if you need help with acquiring error logs.'); ?>
|
6 |
-
</p>
|
7 |
-
<textarea class="support-report"><?php echo esc_html($status_report); ?></textarea>
|
8 |
-
<button class="button button-primary button-large support-report-btn"><?php esc_html_e('Copy', 'printful'); ?></button>
|
9 |
-
<script type="text/javascript">
|
10 |
-
var copyTextareaBtn = document.querySelector('.support-report-btn');
|
11 |
-
|
12 |
-
copyTextareaBtn.addEventListener('click', function() {
|
13 |
-
var copyTextarea = document.querySelector('.support-report');
|
14 |
-
copyTextarea.select();
|
15 |
-
|
16 |
-
try {
|
17 |
-
document.execCommand('copy');
|
18 |
-
} catch (err) {
|
19 |
-
//do nothing
|
20 |
-
}
|
21 |
-
});
|
22 |
-
</script>
|
23 |
</div>
|
1 |
+
<div class="support-report-wrap">
|
2 |
+
<p>
|
3 |
+
<?php esc_html_e('Copy the box content below and add it to your support message', 'printful'); ?>
|
4 |
+
<br/>
|
5 |
+
<?php esc_html_e('Note: this status report may not include an error log. Contact your hosting provider if you need help with acquiring error logs.'); ?>
|
6 |
+
</p>
|
7 |
+
<textarea class="support-report"><?php echo esc_html($status_report); ?></textarea>
|
8 |
+
<button class="button button-primary button-large support-report-btn"><?php esc_html_e('Copy', 'printful'); ?></button>
|
9 |
+
<script type="text/javascript">
|
10 |
+
var copyTextareaBtn = document.querySelector('.support-report-btn');
|
11 |
+
|
12 |
+
copyTextareaBtn.addEventListener('click', function() {
|
13 |
+
var copyTextarea = document.querySelector('.support-report');
|
14 |
+
copyTextarea.select();
|
15 |
+
|
16 |
+
try {
|
17 |
+
document.execCommand('copy');
|
18 |
+
} catch (err) {
|
19 |
+
//do nothing
|
20 |
+
}
|
21 |
+
});
|
22 |
+
</script>
|
23 |
</div>
|
includes/templates/support-info.php
CHANGED
@@ -1,27 +1,27 @@
|
|
1 |
-
<div class="support-info-wrap">
|
2 |
-
|
3 |
-
<div class="support-info-block">
|
4 |
-
<h3><?php esc_html_e('Need help? Get in touch!', 'printful') ?></h3>
|
5 |
-
<p><?php esc_html_e('Email, call, text, or visit us. We\'ve got support teams in the USA and Europe to make sure we\'re there when you need us.', 'printful') ?><br/><?php esc_html_e('We\'d love to hear from you.', 'printful') ?></p>
|
6 |
-
<div class="btn-wrap">
|
7 |
-
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>contacts" class="button button-primary button-large" target="_blank"><?php esc_html_e('Contact support', 'printful') ?></a>
|
8 |
-
</div>
|
9 |
-
</div>
|
10 |
-
|
11 |
-
<div class="support-info-block">
|
12 |
-
<h3><?php esc_html_e('Read our FAQs', 'printful') ?></h3>
|
13 |
-
<p><?php esc_html_e('Getting started made easy – read the FAQs to jumpstart your business.', 'printful') ?><br/><?php esc_html_e('Whether you\'re a video tutorial fan or prefer the written answers – we\'ve got it covered!', 'printful') ?></p>
|
14 |
-
<div class="btn-wrap">
|
15 |
-
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>faq" class="button button-primary button-large" target="_blank"><?php esc_html_e('See Printful FAQ', 'printful') ?></a>
|
16 |
-
</div>
|
17 |
-
</div>
|
18 |
-
|
19 |
-
<div class="support-info-block">
|
20 |
-
<h3><?php esc_html_e('Integration help', 'printful') ?></h3>
|
21 |
-
<p><?php esc_html_e('Are you experiencing technical issues? Solve them on your own by reading these helpful guides and video tutorials.', 'printful') ?></p>
|
22 |
-
<div class="btn-wrap">
|
23 |
-
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>faq/integrations/woocommerce" class="button button-primary button-large" target="_blank"><?php esc_html_e('Integration help', 'printful') ?></a>
|
24 |
-
</div>
|
25 |
-
</div>
|
26 |
-
|
27 |
</div>
|
1 |
+
<div class="support-info-wrap">
|
2 |
+
|
3 |
+
<div class="support-info-block">
|
4 |
+
<h3><?php esc_html_e('Need help? Get in touch!', 'printful') ?></h3>
|
5 |
+
<p><?php esc_html_e('Email, call, text, or visit us. We\'ve got support teams in the USA and Europe to make sure we\'re there when you need us.', 'printful') ?><br/><?php esc_html_e('We\'d love to hear from you.', 'printful') ?></p>
|
6 |
+
<div class="btn-wrap">
|
7 |
+
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>contacts" class="button button-primary button-large" target="_blank"><?php esc_html_e('Contact support', 'printful') ?></a>
|
8 |
+
</div>
|
9 |
+
</div>
|
10 |
+
|
11 |
+
<div class="support-info-block">
|
12 |
+
<h3><?php esc_html_e('Read our FAQs', 'printful') ?></h3>
|
13 |
+
<p><?php esc_html_e('Getting started made easy – read the FAQs to jumpstart your business.', 'printful') ?><br/><?php esc_html_e('Whether you\'re a video tutorial fan or prefer the written answers – we\'ve got it covered!', 'printful') ?></p>
|
14 |
+
<div class="btn-wrap">
|
15 |
+
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>faq" class="button button-primary button-large" target="_blank"><?php esc_html_e('See Printful FAQ', 'printful') ?></a>
|
16 |
+
</div>
|
17 |
+
</div>
|
18 |
+
|
19 |
+
<div class="support-info-block">
|
20 |
+
<h3><?php esc_html_e('Integration help', 'printful') ?></h3>
|
21 |
+
<p><?php esc_html_e('Are you experiencing technical issues? Solve them on your own by reading these helpful guides and video tutorials.', 'printful') ?></p>
|
22 |
+
<div class="btn-wrap">
|
23 |
+
<a href="<?php echo esc_url(Printful_Base::get_printful_host()); ?>faq/integrations/woocommerce" class="button button-primary button-large" target="_blank"><?php esc_html_e('Integration help', 'printful') ?></a>
|
24 |
+
</div>
|
25 |
+
</div>
|
26 |
+
|
27 |
</div>
|
printful-shipping.php
CHANGED
@@ -3,13 +3,13 @@
|
|
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
|
10 |
Text Domain: printful
|
11 |
WC requires at least: 3.0.0
|
12 |
-
WC tested up to: 4.
|
13 |
*/
|
14 |
|
15 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
@@ -20,7 +20,7 @@ if ( ! defined( 'PF_PLUGIN_FILE' ) ) {
|
|
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 |
|
@@ -59,6 +59,7 @@ class Printful_Base {
|
|
59 |
require_once 'includes/class-printful-size-chart-tab.php';
|
60 |
require_once 'includes/class-printful-template.php';
|
61 |
require_once 'includes/class-printful-customizer.php';
|
|
|
62 |
|
63 |
//launch init
|
64 |
Printful_Taxes::init();
|
@@ -68,6 +69,7 @@ class Printful_Base {
|
|
68 |
Printful_Size_Chart_Tab::init();
|
69 |
Printful_Template::init();
|
70 |
Printful_Customizer::init();
|
|
|
71 |
|
72 |
//hook ajax callbacks
|
73 |
add_action( 'wp_ajax_save_printful_settings', array( 'Printful_Admin_Settings', 'save_printful_settings' ) );
|
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.14
|
7 |
Author: Printful
|
8 |
Author URI: http://www.printful.com
|
9 |
License: GPL2 http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
Text Domain: printful
|
11 |
WC requires at least: 3.0.0
|
12 |
+
WC tested up to: 4.4
|
13 |
*/
|
14 |
|
15 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
20 |
|
21 |
class Printful_Base {
|
22 |
|
23 |
+
const VERSION = '2.1.14';
|
24 |
const PF_HOST = 'https://www.printful.com/';
|
25 |
const PF_API_HOST = 'https://api.printful.com/';
|
26 |
|
59 |
require_once 'includes/class-printful-size-chart-tab.php';
|
60 |
require_once 'includes/class-printful-template.php';
|
61 |
require_once 'includes/class-printful-customizer.php';
|
62 |
+
require_once 'includes/class-printful-size-guide.php';
|
63 |
|
64 |
//launch init
|
65 |
Printful_Taxes::init();
|
69 |
Printful_Size_Chart_Tab::init();
|
70 |
Printful_Template::init();
|
71 |
Printful_Customizer::init();
|
72 |
+
Printful_Size_Guide::init();
|
73 |
|
74 |
//hook ajax callbacks
|
75 |
add_action( 'wp_ajax_save_printful_settings', array( 'Printful_Admin_Settings', 'save_printful_settings' ) );
|
readme.txt
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
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: 4.9
|
5 |
-
Tested up to: 5.
|
6 |
Requires PHP: 5.6
|
7 |
-
Stable tag: 2.1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -65,6 +65,9 @@ Go to https://www.printful.com/dashboard/store , select your WooCommerce store,
|
|
65 |
|
66 |
== Upgrade Notice ==
|
67 |
|
|
|
|
|
|
|
68 |
= 2.1.13 =
|
69 |
Woocommerce compatibility raised to 4.3
|
70 |
|
@@ -181,6 +184,9 @@ First release
|
|
181 |
|
182 |
== Changelog ==
|
183 |
|
|
|
|
|
|
|
184 |
= 2.1.13 =
|
185 |
* Improved support for WooCommerce 4.3
|
186 |
|
2 |
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: 4.9
|
5 |
+
Tested up to: 5.5
|
6 |
Requires PHP: 5.6
|
7 |
+
Stable tag: 2.1.14
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
65 |
|
66 |
== Upgrade Notice ==
|
67 |
|
68 |
+
= 2.1.14 =
|
69 |
+
Advanced size guide feature
|
70 |
+
|
71 |
= 2.1.13 =
|
72 |
Woocommerce compatibility raised to 4.3
|
73 |
|
184 |
|
185 |
== Changelog ==
|
186 |
|
187 |
+
= 2.1.14 =
|
188 |
+
Advanced size guide feature
|
189 |
+
|
190 |
= 2.1.13 =
|
191 |
* Improved support for WooCommerce 4.3
|
192 |
|