├── admin
├── assets
│ ├── colorpicker
│ │ ├── spectrum.css
│ │ └── spectrum.js
│ ├── css
│ │ ├── delete.png
│ │ ├── edit.png
│ │ ├── help.png
│ │ └── thwepo-admin.min.css
│ └── js
│ │ └── thwepo-admin.min.js
├── class-thwepo-admin-form-field.php
├── class-thwepo-admin-form-section.php
├── class-thwepo-admin-form.php
├── class-thwepo-admin-settings-advanced.php
├── class-thwepo-admin-settings-general.php
├── class-thwepo-admin-settings-license.php
├── class-thwepo-admin-settings.php
├── class-thwepo-admin-utils.php
├── class-thwepo-admin.php
└── index.php
├── class-thwepo-license-manager.php
├── includes
├── class-thwepo-activator.php
├── class-thwepo-autoloader.php
├── class-thwepo-data.php
├── class-thwepo-deactivator.php
├── class-thwepo-file.php
├── class-thwepo-i18n.php
├── class-thwepo-loader.php
├── class-thwepo-price.php
├── class-thwepo.php
├── compatibility
│ └── class-wepo-wpml-currency-switcher-handler.php
├── index.php
├── model
│ ├── class-wepo-section.php
│ ├── fields
│ │ ├── class-wepo-field-checkbox.php
│ │ ├── class-wepo-field-checkboxgroup.php
│ │ ├── class-wepo-field-colorpicker.php
│ │ ├── class-wepo-field-datepicker.php
│ │ ├── class-wepo-field-factory.php
│ │ ├── class-wepo-field-file.php
│ │ ├── class-wepo-field-heading.php
│ │ ├── class-wepo-field-hidden.php
│ │ ├── class-wepo-field-html.php
│ │ ├── class-wepo-field-inputtext.php
│ │ ├── class-wepo-field-label.php
│ │ ├── class-wepo-field-multiselect.php
│ │ ├── class-wepo-field-number.php
│ │ ├── class-wepo-field-password.php
│ │ ├── class-wepo-field-radio.php
│ │ ├── class-wepo-field-select.php
│ │ ├── class-wepo-field-tel.php
│ │ ├── class-wepo-field-textarea.php
│ │ ├── class-wepo-field-timepicker.php
│ │ └── class-wepo-field.php
│ └── rules
│ │ ├── class-wepo-condition-set.php
│ │ ├── class-wepo-condition.php
│ │ ├── class-wepo-rule-set.php
│ │ └── class-wepo-rule.php
└── utils
│ ├── class-thwepo-utils-condition.php
│ ├── class-thwepo-utils-core.php
│ ├── class-thwepo-utils-field.php
│ ├── class-thwepo-utils-section.php
│ └── class-thwepo-utils.php
├── index.php
├── languages
└── woocommerce-extra-product-options-pro.pot
├── public
├── assets
│ ├── css
│ │ └── thwepo-public.min.css
│ └── js
│ │ ├── jquery-ui-i18n.min.js
│ │ ├── thwepo-public.min.js
│ │ └── timepicker
│ │ ├── jquery.timepicker.css
│ │ └── jquery.timepicker.min.js
├── class-thwepo-public.php
└── index.php
├── uninstall.php
└── woocommerce-extra-product-options-pro.php
/admin/assets/colorpicker/spectrum.css:
--------------------------------------------------------------------------------
1 | /***
2 | Spectrum Colorpicker v1.8.0
3 | https://github.com/bgrins/spectrum
4 | Author: Brian Grinstead
5 | License: MIT
6 | ***/
7 |
8 | .sp-container {
9 | position:absolute;
10 | top:0;
11 | left:0;
12 | display:inline-block;
13 | *display: inline;
14 | *zoom: 1;
15 | /* https://github.com/bgrins/spectrum/issues/40 */
16 | z-index: 9999994;
17 | overflow: hidden;
18 | }
19 | .sp-container.sp-flat {
20 | position: relative;
21 | }
22 |
23 | /* Fix for * { box-sizing: border-box; } */
24 | .sp-container,
25 | .sp-container * {
26 | -webkit-box-sizing: content-box;
27 | -moz-box-sizing: content-box;
28 | box-sizing: content-box;
29 | }
30 |
31 | /* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
32 | .sp-top {
33 | position:relative;
34 | width: 100%;
35 | display:inline-block;
36 | }
37 | .sp-top-inner {
38 | position:absolute;
39 | top:0;
40 | left:0;
41 | bottom:0;
42 | right:0;
43 | }
44 | .sp-color {
45 | position: absolute;
46 | top:0;
47 | left:0;
48 | bottom:0;
49 | right:20%;
50 | }
51 | .sp-hue {
52 | position: absolute;
53 | top:0;
54 | right:0;
55 | bottom:0;
56 | left:84%;
57 | height: 100%;
58 | }
59 |
60 | .sp-clear-enabled .sp-hue {
61 | top:33px;
62 | height: 77.5%;
63 | }
64 |
65 | .sp-fill {
66 | padding-top: 80%;
67 | }
68 | .sp-sat, .sp-val {
69 | position: absolute;
70 | top:0;
71 | left:0;
72 | right:0;
73 | bottom:0;
74 | }
75 |
76 | .sp-alpha-enabled .sp-top {
77 | margin-bottom: 18px;
78 | }
79 | .sp-alpha-enabled .sp-alpha {
80 | display: block;
81 | }
82 | .sp-alpha-handle {
83 | position:absolute;
84 | top:-4px;
85 | bottom: -4px;
86 | width: 6px;
87 | left: 50%;
88 | cursor: pointer;
89 | border: 1px solid black;
90 | background: white;
91 | opacity: .8;
92 | }
93 | .sp-alpha {
94 | display: none;
95 | position: absolute;
96 | bottom: -14px;
97 | right: 0;
98 | left: 0;
99 | height: 8px;
100 | }
101 | .sp-alpha-inner {
102 | border: solid 1px #333;
103 | }
104 |
105 | .sp-clear {
106 | display: none;
107 | }
108 |
109 | .sp-clear.sp-clear-display {
110 | background-position: center;
111 | }
112 |
113 | .sp-clear-enabled .sp-clear {
114 | display: block;
115 | position:absolute;
116 | top:0px;
117 | right:0;
118 | bottom:0;
119 | left:84%;
120 | height: 28px;
121 | }
122 |
123 | /* Don't allow text selection */
124 | .sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
125 | -webkit-user-select:none;
126 | -moz-user-select: -moz-none;
127 | -o-user-select:none;
128 | user-select: none;
129 | }
130 |
131 | .sp-container.sp-input-disabled .sp-input-container {
132 | display: none;
133 | }
134 | .sp-container.sp-buttons-disabled .sp-button-container {
135 | display: none;
136 | }
137 | .sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
138 | display: none;
139 | }
140 | .sp-palette-only .sp-picker-container {
141 | display: none;
142 | }
143 | .sp-palette-disabled .sp-palette-container {
144 | display: none;
145 | }
146 |
147 | .sp-initial-disabled .sp-initial {
148 | display: none;
149 | }
150 |
151 |
152 | /* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
153 | .sp-sat {
154 | background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
155 | background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
156 | background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
157 | background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
158 | background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
159 | background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
160 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
161 | filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
162 | }
163 | .sp-val {
164 | background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
165 | background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
166 | background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
167 | background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
168 | background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
169 | background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
170 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
171 | filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
172 | }
173 |
174 | .sp-hue {
175 | background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
176 | background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
177 | background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
178 | background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
179 | background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
180 | background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
181 | }
182 |
183 | /* IE filters do not support multiple color stops.
184 | Generate 6 divs, line them up, and do two color gradients for each.
185 | Yes, really.
186 | */
187 | .sp-1 {
188 | height:17%;
189 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
190 | }
191 | .sp-2 {
192 | height:16%;
193 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
194 | }
195 | .sp-3 {
196 | height:17%;
197 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
198 | }
199 | .sp-4 {
200 | height:17%;
201 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
202 | }
203 | .sp-5 {
204 | height:16%;
205 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
206 | }
207 | .sp-6 {
208 | height:17%;
209 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
210 | }
211 |
212 | .sp-hidden {
213 | display: none !important;
214 | }
215 |
216 | /* Clearfix hack */
217 | .sp-cf:before, .sp-cf:after { content: ""; display: table; }
218 | .sp-cf:after { clear: both; }
219 | .sp-cf { *zoom: 1; }
220 |
221 | /* Mobile devices, make hue slider bigger so it is easier to slide */
222 | @media (max-device-width: 480px) {
223 | .sp-color { right: 40%; }
224 | .sp-hue { left: 63%; }
225 | .sp-fill { padding-top: 60%; }
226 | }
227 | .sp-dragger {
228 | border-radius: 5px;
229 | height: 5px;
230 | width: 5px;
231 | border: 1px solid #fff;
232 | background: #000;
233 | cursor: pointer;
234 | position:absolute;
235 | top:0;
236 | left: 0;
237 | }
238 | .sp-slider {
239 | position: absolute;
240 | top:0;
241 | cursor:pointer;
242 | height: 3px;
243 | left: -1px;
244 | right: -1px;
245 | border: 1px solid #000;
246 | background: white;
247 | opacity: .8;
248 | }
249 |
250 | /*
251 | Theme authors:
252 | Here are the basic themeable display options (colors, fonts, global widths).
253 | See http://bgrins.github.io/spectrum/themes/ for instructions.
254 | */
255 |
256 | .sp-container {
257 | border-radius: 0;
258 | background-color: #ECECEC;
259 | border: solid 1px #f0c49B;
260 | padding: 0;
261 | }
262 | .sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
263 | font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
264 | -webkit-box-sizing: border-box;
265 | -moz-box-sizing: border-box;
266 | -ms-box-sizing: border-box;
267 | box-sizing: border-box;
268 | }
269 | .sp-top {
270 | margin-bottom: 3px;
271 | }
272 | .sp-color, .sp-hue, .sp-clear {
273 | border: solid 1px #666;
274 | }
275 |
276 | /* Input */
277 | .sp-input-container {
278 | float:right;
279 | width: 100px;
280 | margin-bottom: 4px;
281 | }
282 | .sp-initial-disabled .sp-input-container {
283 | width: 100%;
284 | }
285 | .sp-input {
286 | font-size: 12px !important;
287 | border: 1px inset;
288 | padding: 4px 5px;
289 | margin: 0;
290 | width: 100%;
291 | background:transparent;
292 | border-radius: 3px;
293 | color: #222;
294 | }
295 | .sp-input:focus {
296 | border: 1px solid orange;
297 | }
298 | .sp-input.sp-validation-error {
299 | border: 1px solid red;
300 | background: #fdd;
301 | }
302 | .sp-picker-container , .sp-palette-container {
303 | float:left;
304 | position: relative;
305 | padding: 10px;
306 | padding-bottom: 300px;
307 | margin-bottom: -290px;
308 | }
309 | .sp-picker-container {
310 | width: 172px;
311 | border-left: solid 1px #fff;
312 | }
313 |
314 | /* Palettes */
315 | .sp-palette-container {
316 | border-right: solid 1px #ccc;
317 | }
318 |
319 | .sp-palette-only .sp-palette-container {
320 | border: 0;
321 | }
322 |
323 | .sp-palette .sp-thumb-el {
324 | display: block;
325 | position:relative;
326 | float:left;
327 | width: 24px;
328 | height: 15px;
329 | margin: 3px;
330 | cursor: pointer;
331 | border:solid 2px transparent;
332 | }
333 | .sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
334 | border-color: orange;
335 | }
336 | .sp-thumb-el {
337 | position:relative;
338 | }
339 |
340 | /* Initial */
341 | .sp-initial {
342 | float: left;
343 | border: solid 1px #333;
344 | }
345 | .sp-initial span {
346 | width: 30px;
347 | height: 25px;
348 | border:none;
349 | display:block;
350 | float:left;
351 | margin:0;
352 | }
353 |
354 | .sp-initial .sp-clear-display {
355 | background-position: center;
356 | }
357 |
358 | /* Buttons */
359 | .sp-palette-button-container,
360 | .sp-button-container {
361 | float: right;
362 | }
363 |
364 | /* Replacer (the little preview div that shows up instead of the ) */
365 | .sp-replacer {
366 | margin:0;
367 | overflow:hidden;
368 | cursor:pointer;
369 | padding: 4px;
370 | display:inline-block;
371 | *zoom: 1;
372 | *display: inline;
373 | border: solid 1px #91765d;
374 | background: #eee;
375 | color: #333;
376 | vertical-align: middle;
377 | }
378 | .sp-replacer:hover, .sp-replacer.sp-active {
379 | border-color: #F0C49B;
380 | color: #111;
381 | }
382 | .sp-replacer.sp-disabled {
383 | cursor:default;
384 | border-color: silver;
385 | color: silver;
386 | }
387 | .sp-dd {
388 | padding: 2px 0;
389 | height: 16px;
390 | line-height: 16px;
391 | float:left;
392 | font-size:10px;
393 | }
394 | .sp-preview {
395 | position:relative;
396 | width:25px;
397 | height: 20px;
398 | border: solid 1px #222;
399 | margin-right: 5px;
400 | float:left;
401 | z-index: 0;
402 | }
403 |
404 | .sp-palette {
405 | *width: 220px;
406 | max-width: 220px;
407 | }
408 | .sp-palette .sp-thumb-el {
409 | width:16px;
410 | height: 16px;
411 | margin:2px 1px;
412 | border: solid 1px #d0d0d0;
413 | }
414 |
415 | .sp-container {
416 | padding-bottom:0;
417 | }
418 |
419 |
420 | /* Buttons: http://hellohappy.org/css3-buttons/ */
421 | .sp-container button {
422 | background-color: #eeeeee;
423 | background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
424 | background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
425 | background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
426 | background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
427 | background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
428 | border: 1px solid #ccc;
429 | border-bottom: 1px solid #bbb;
430 | border-radius: 3px;
431 | color: #333;
432 | font-size: 14px;
433 | line-height: 1;
434 | padding: 5px 4px;
435 | text-align: center;
436 | text-shadow: 0 1px 0 #eee;
437 | vertical-align: middle;
438 | }
439 | .sp-container button:hover {
440 | background-color: #dddddd;
441 | background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
442 | background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
443 | background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
444 | background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
445 | background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
446 | border: 1px solid #bbb;
447 | border-bottom: 1px solid #999;
448 | cursor: pointer;
449 | text-shadow: 0 1px 0 #ddd;
450 | }
451 | .sp-container button:active {
452 | border: 1px solid #aaa;
453 | border-bottom: 1px solid #888;
454 | -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
455 | -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
456 | -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
457 | -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
458 | box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
459 | }
460 | .sp-cancel {
461 | font-size: 11px;
462 | color: #d93f3f !important;
463 | margin:0;
464 | padding:2px;
465 | margin-right: 5px;
466 | vertical-align: middle;
467 | text-decoration:none;
468 |
469 | }
470 | .sp-cancel:hover {
471 | color: #d93f3f !important;
472 | text-decoration: underline;
473 | }
474 |
475 |
476 | .sp-palette span:hover, .sp-palette span.sp-thumb-active {
477 | border-color: #000;
478 | }
479 |
480 | .sp-preview, .sp-alpha, .sp-thumb-el {
481 | position:relative;
482 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
483 | }
484 | .sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
485 | display:block;
486 | position:absolute;
487 | top:0;left:0;bottom:0;right:0;
488 | }
489 |
490 | .sp-palette .sp-thumb-inner {
491 | background-position: 50% 50%;
492 | background-repeat: no-repeat;
493 | }
494 |
495 | .sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
496 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
497 | }
498 |
499 | .sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
500 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
501 | }
502 |
503 | .sp-clear-display {
504 | background-repeat:no-repeat;
505 | background-position: center;
506 | background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
507 | }
508 |
--------------------------------------------------------------------------------
/admin/assets/css/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pro-WebTech/woocommerce-temp/6a970ed112b66beb0540d3ce2bf7200cb94f67c6/admin/assets/css/delete.png
--------------------------------------------------------------------------------
/admin/assets/css/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pro-WebTech/woocommerce-temp/6a970ed112b66beb0540d3ce2bf7200cb94f67c6/admin/assets/css/edit.png
--------------------------------------------------------------------------------
/admin/assets/css/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pro-WebTech/woocommerce-temp/6a970ed112b66beb0540d3ce2bf7200cb94f67c6/admin/assets/css/help.png
--------------------------------------------------------------------------------
/admin/assets/css/thwepo-admin.min.css:
--------------------------------------------------------------------------------
1 | .align-center{text-align:center!important}.woocommerce-message{margin-top:10px}.err_msgs{color:red}.empty-msg-row{padding:20px 0!important;text-align:center}.status-active{font-size:15px;color:green}.status-deactive{font-size:15px;color:red}.thpladmin-subtitle{font-size:11px;color:#666}.thpladmin-notice a.button-primary{font-size:14px;color:#FFF;background-color:#D9534F;border-color:#D43F3A;line-height:38px;height:40px;padding-left:20px;padding-right:20px}.thpladmin-notice a.button-primary:hover{background-color:#D2322D;border-color:#AC2925}table.thpladmin_fields_table td.sort{cursor:move;font-size:15px;text-align:center}table.thpladmin_fields_table td.sort::before{content:'\f333';font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}.thpl_logic_label,.thpl_logic_link{cursor:default;display:block;float:left;border:1px solid gray;padding:0 5px;margin-left:5px;margin-right:5px;border-radius:2px}.thpl_logic_link{cursor:pointer;text-decoration:none;color:#FFF!important;background-color:#00A0D2;border:1px solid #0073AA}a.thpl_delete_icon{color:red}a.thpl_delete_icon:hover{opacity:.6;filter:alpha(opacity=60)}.thpladmin-license-settings .info-text,.thpladmin-license-settings-grid{margin-top:30px}.thpladmin-license-settings-grid .dashicons{margin-left:3px;margin-top:8px}.thpladmin-license-settings-grid input[type=text]{padding:5px;width:300px}.thpladmin-license-settings-grid p.submit{margin-top:20px}.thpladmin-license-settings-grid table{margin-top:10px}.thpladmin-license-settings-grid table td,.thpladmin-license-settings-grid table th{padding:5px 0;font-weight:400;vertical-align:middle}.thpladmin-license-settings-grid h2{font-size:14px;margin-bottom:9px;padding-bottom:5px;vertical-align:middle;font-weight:700;border-bottom:1px dashed #cecece}.thpladmin-tab{width:100%;border:0 solid #d4d4d1;border-top:0;background-color:#fff;float:left}.thpladmin-tabs-menu{width:100%;margin:10px 0 0;float:left;clear:both;border-bottom:1px solid #bcd4e6}.thpladmin-tabs-menu li{float:left;margin-right:5px;margin-bottom:-1px;border:1px solid #bcd4e6;outline:transparent solid 1px;border-radius:4px 4px 0 0;background:#e1ecf4}.thpladmin-tabs-menu li.current{color:#555;position:relative;background-color:#fff;border-bottom:1px solid #fff;box-shadow:none}.thpladmin-tabs-menu li.first{margin-left:20px}.thpladmin-tabs-menu li a{font-size:18px;display:block;padding:12px 20px;text-decoration:none;color:#9fc2db;-webkit-transition:color .2s;transition:color .2s}.thpladmin-tabs-menu li a:focus{outline:0;box-shadow:none}.thpladmin-tabs-menu .current a{color:#2e7da3}.thpladmin-tab-content{padding:0;display:none;min-height:200px;max-height:485px;color:#000}.thpladmin-sections{list-style:none;margin:8px 0 0;padding:0;font-size:13px;color:#666}.thpladmin-sections li{display:inline-block;margin:0;padding:0;white-space:nowrap}.thpladmin-sections a.current{font-weight:600;border:none;color:#000}.thpladmin-sections a{line-height:2;padding:.2em;text-decoration:none}.thpladmin-sections .delete_section img,.thpladmin-sections a.edit_section img{width:12px;height:12px}.thpladmin-sections a.add_link{margin-left:30px;background-color:#00A0D2;border:1px solid #0073AA;color:#FFF;padding:2px 5px;border-radius:3px}.thpladmin-sections a.add_link:hover{background-color:#0073AA}.thpladmin-form-table td{padding:5px 0}.thpladmin-form-table td.thpladmin-form-section-title{font-weight:700;border-bottom:1px dashed #cecece}.product_page_th_extra_product_options_pro .ui-dialog{z-index:9990;height:auto!important;padding:0;border-color:#0071a1;border-radius:0}.product_page_th_extra_product_options_pro .ui-widget-overlay{position:fixed}.product_page_th_extra_product_options_pro .ui-dialog td{padding:2px 0}.product_page_th_extra_product_options_pro .ui-dialog .ui-widget-header{color:#fff;background:#004f70;background-image:linear-gradient(#004f70,#005a80)}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-titlebar{height:30px;padding:.6em 1em .4em;border:0;border-radius:0}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-title{line-height:20px;font-weight:400}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-titlebar-close{border:1px solid #fff;background-color:#fff;right:.6em}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-titlebar-close:before{display:none}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-titlebar-close .ui-icon{background-color:#fff}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-buttonpane{border-color:#0071a1}.product_page_th_extra_product_options_pro .ui-dialog .ui-dialog-buttonpane button{color:#0071a1;border-color:#0071a1;background:#f3f5f6;vertical-align:top;height:auto}.product_page_th_extra_product_options_pro .ui-dialog input[type=text],.product_page_th_extra_product_options_pro .ui-dialog select{border-radius:4px;border:1px solid #7e8993;height:34px;padding:0 8px}.product_page_th_extra_product_options_pro .select2-container--default .select2-selection--multiple .select2-selection__rendered{padding:0}.product_page_th_extra_product_options_pro .select2-container--default .select2-selection--multiple .select2-selection__rendered li{font-size:.8em;margin:4px 4px 0 0}.product_page_th_extra_product_options_pro .select2-container--default .select2-selection--multiple .select2-selection__rendered li.select2-search{margin:0;height:26px;width:auto}.thpladmin-popup-wrapper{max-height:400px;overflow-y:scroll}.thpladmin-popup-wrapper input[type=text]:disabled,.thpladmin-popup-wrapper select:disabled{background:#f6f6f6}h1.nav-tab-wrapper,h2.nav-tab-wrapper,h3.nav-tab-wrapper{border-bottom:1px solid #CCC;padding-bottom:0;padding-left:10px}.thpladmin-dynamic-row-table .action-cell{width:30px;text-align:center}.thpladmin-dynamic-row-table .action-cell a.btn{background-color:#00A0D2;border:1px solid #0073AA;color:#FFF;padding:2px 5px;border-radius:3px;font-size:12px;text-decoration:none}.thpladmin-dynamic-row-table .action-cell a.btn-blue{background-color:#00A0D2;border:1px solid #0073AA}.thpladmin-dynamic-row-table .action-cell a.btn-red{background-color:#f66;border:1px solid #ff4c4c}.thpladmin-dynamic-row-table .action-cell a.dashicons{line-height:inherit;font-size:18px;color:#fff;border-radius:3px;box-shadow:0 1px 0 #ccc}.thpladmin-dynamic-row-table .action-cell a.dashicons-plus{background-color:#00A0D2;border:1px solid #0073AA}.thpladmin-dynamic-row-table .action-cell a.dashicons-no-alt{background-color:#f66;border:1px solid #ff4c4c}table.thpladmin-dynamic-row-table td.sort{padding:0;cursor:move;font-size:20px;text-align:center;vertical-align:middle}table.thpladmin-dynamic-row-table td.sort::before{content:'\f333';font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.thpladmin_fields_table tr.strikeout td{background:rgba(255,0,0,.4)!important;opacity:.6;text-decoration:line-through}.thpladmin_fields_table tr.thpladmin-disabled td{opacity:.4}.thpladmin_fields_table tr.thpladmin-disabled td.td_select{opacity:1}.thpladmin_fields_table .td_actions{width:90px}.thpladmin_fields_table .td_enabled{width:80px}.thpladmin_fields_table .td_clear{width:65px}.thpladmin_fields_table .td_required{width:85px}.thpladmin_fields_table .td_select{width:45px}.thpladmin_fields_table .td_type{width:150px}.thpladmin_fields_table .td_validate{text-transform:capitalize}.thpladmin_fields_table th.status{white-space:nowrap}.thpladmin_fields_table .dashicons{line-height:inherit}.thpladmin_fields_table .td_actions .dashicons{background-color:#f7f7f7;border:1px solid #ccc;border-radius:3px;padding:0 2px 2px;box-shadow:0 1px 0 #ccc;webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.thpladmin_fields_table .td_actions .dashicons.disabled{color:#ccc;border:1px solid #e9e9e9;cursor:default}.thpladmin-sections .dashicons,.thpladmin_fields_table .td_actions .dashicons-admin-page,.thpladmin_fields_table .td_actions .dashicons-edit{cursor:pointer}.thpladmin-sections .dashicons-no{color:#ff4c4c}.iris-picker{z-index:100;display:none;position:absolute!important;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:0 0!important}.iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.thpladmin-colorpickpreview{padding:7px 10px 7px 20px;border:1px solid #7e8993;border-radius:4px 0 0 4px;border-right:1;background-color:#FFF}.product_page_th_extra_product_options_pro .thpladmin-colorpick{border-left:0!important;margin-left:0!important;border-top-left-radius:0!important;border-bottom-left-radius:0!important}.select2-drop-mask{z-index:99999998!important}.select2-container,.select2-drop{z-index:99999999!important}.select2-container .select2-search--inline .select2-search__field{margin-top:0!important;margin-bottom:0!important;border:0!important}.select2-container .select2-search__field{min-width:0!important;background-image:none!important}#thwepo-tab-general_edit,#thwepo-tab-general_new{display:block}#thwepo-tab-general_edit h4,#thwepo-tab-general_new h4,#thwepo-tab-styles_new h4{border-bottom:1px dotted #dededede}.thwepo_tooltip{float:right;display:inline;position:relative;font-size:12px;height:100%;z-index:99999999}.thwepo_tooltip img{padding:0;vertical-align:middle;cursor:help;border:none;height:16px;width:16px}.thwepo_tooltip:hover:after{background:#333;background:rgba(0,0,0,1);border-radius:5px;bottom:26px;color:#fff;content:attr(title);left:-100px;padding:10px 15px;position:absolute;z-index:9998;width:350px}.thwepo_tooltip:hover:before{border:solid;border-color:#000 transparent;border-width:6px 6px 0;bottom:20px;content:"";left:50%;position:absolute;z-index:9999}:root{--primary-bg-color:#007cba;--primary-text-color:#0071a1;--primary-border-color:#0071a1;--primary-alt-bg-color:#f3f5f6;--primary-alt-text-color:#0071a1;--primary-alt-border-color:#0071a1}*{box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}ol,ul{margin-top:0;margin-bottom:10px}:after,:before{box-sizing:border-box}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{cursor:pointer;text-decoration:none;background-color:transparent}.btn-link,a{color:#528ff0}.wp-core-ui select{line-height:2;border-color:#e2e2e2}.pull-right{float:right!important}.ml-30{margin-left:30px!important}.mt-10{margin-top:10px!important}.mt-20{margin-top:20px!important}.p-0{padding:0!important}.ph-5{padding-left:5px!important;padding-right:5px!important}.pv-2{padding-top:2px!important;padding-bottom:2px!important}.thwepo-wrap div.thwepo-notice{margin:10px 20px 0 2px}.thwepo-wrap input[type=text],.thwepo-wrap input[type=number],.thwepo-wrap select,.thwepo-wrap textarea{color:#32373c;line-height:1;min-height:30px;height:36px;width:auto;background-color:#fff;border:1px solid #e2e2e2;border-radius:2px;overflow:hidden;font-size:14px;padding:0 12px;box-shadow:0 0 0 transparent}.thwepo-wrap textarea{height:auto;overflow:auto;padding:2px 6px;line-height:1.5;resize:vertical}.thwepo-wrap input[type=text]:disabled,.thwepo-wrap input[type=number]:disabled,.thwepo-wrap select:disabled,.thwepo-wrap textarea:disabled{color:#a0a5aa;border-color:#ddd;background-color:#f7f7f7}.thwepo-wrap input[type=text]:disabled::placeholder,.thwepo-wrap input[type=number]:disabled::placeholder,.thwepo-wrap select:disabled::placeholder,.thwepo-wrap textarea:disabled::placeholder{color:#a0a5aa}.thwepo-wrap .btn{display:inline-block;background-image:none;font-size:14px;font-weight:400;text-align:center;vertical-align:middle;white-space:nowrap;cursor:pointer;touch-action:manipulation;line-height:1;border-width:1px;border-style:solid;border-radius:2px;outline:0;margin:0;padding:12px 20px;box-sizing:border-box;-webkit-appearance:none;-webkit-box-sizing:border-box;transition:.1s;-webkit-transition:.1s;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;color:var(--primary-alt-text-color);background-color:var(--primary-alt-bg-color);border-color:var(--primary-alt-border-color)}.thwepo-wrap .btn:hover{opacity:.9}.thwepo-wrap .btn-small{font-size:13px;padding:8px 10px;border-radius:2px}.thwepo-wrap .btn-tiny{font-size:13px;padding:5px;border-radius:2px}.thwepo-wrap .btn-primary{color:#fff;background-color:var(--primary-bg-color);border-color:var(--primary-border-color)}.thwepo-wrap .btn-primary-alt{color:var(--primary-alt-text-color);background-color:var(--primary-alt-bg-color);border-color:var(--primary-alt-border-color)}.thwepo-wrap .btn-danger{color:#fff;background-color:#f44336;border-color:#c3352b}.thwepo-wrap .btn:disabled,.thwepo-wrap .btn[disabled]{color:#cbcbcb;border-color:#cbcbcb;background-color:#fcfcfc;cursor:default}.thwepo-checkbox{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}.thwepo-checkbox .cb-input,.thwepo-radio .rb-input{display:block;height:0;margin:0;opacity:0;line-height:normal;box-sizing:border-box;overflow:hidden}.thwepo-checkbox .cb-el{width:16px;margin-top:2px;margin-right:8px;height:16px;background:#fff;border-radius:2px;float:left;transition:.3s;cursor:pointer;border:1px solid #ccc}.thwepo-checkbox .cb-el::after{content:'';display:block;width:6px;height:11px;opacity:0;transition:.2s;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg) scale(1.5);margin:0 0 0 4px}.thwepo-checkbox .cb-label{font-size:14px;cursor:pointer;white-space:normal;display:inline-block;font-weight:400;vertical-align:middle}.thwepo-checkbox :checked+.cb-el{background:#528ff0;border-color:#528ff0}.thwepo-checkbox :checked+.cb-el::after{opacity:1;transform:rotate(45deg)}.thwepo-input-wrap{font-weight:400;display:block;margin:24px 0 8px;position:relative}.thwepo-input-wrap .label{float:left;width:172px;text-align:right;margin-bottom:4px;font-weight:700;position:relative}.thwepo-input-wrap.required .label::after{content:'*';font-size:12px;position:absolute;margin-left:1px;top:0;color:#f05050}.thwepo-input-wrap .content{margin-left:190px;position:relative}.thwepo-input-wrap.small .iel-wrapper{width:260px}.thwepo-input-wrap .thwepo-inputtext,.thwepo-input-wrap .thwepo-select{width:100%}.thpladmin-modal-mask{position:fixed;background-color:rgba(17,30,60,.6);top:0;left:0;width:100%;height:100%;z-index:9999;overflow:scroll;transition:opacity 250ms ease-in-out;display:none}.thpladmin-modal .modal-container{position:absolute;background:#fff;border-radius:2px;overflow:hidden;left:50%;top:50%;transform:translate(-50%,-50%);width:90%;max-width:960px;min-height:560px;height:80vh;max-height:640px;animation:appear-down 250ms ease-in-out}.thpladmin-modal .modal-close{position:absolute;color:#58666e;font-size:30px;padding:9px 12px 11px;right:8px;top:8px;line-height:20px;cursor:pointer;z-index:10;user-select:none}.thpladmin-modal .form-wizard{max-width:1024px;height:80vh;max-height:640px;min-height:560px;background:#fafafa;position:relative}.thpladmin-modal .wizard aside{padding:24px 0;width:240px;background:#fff;position:absolute;height:100%;border-right:1px solid #eee}.thpladmin-modal .wizard aside p,.thpladmin-modal .wizard aside side-title{padding:0 24px}.thpladmin-modal .wizard aside side-title{font-size:18px;font-weight:700;display:block;margin-bottom:16px}.thpladmin-modal .form-wizard .sub-title,.thpladmin-modal .form-wizard main-title{text-transform:uppercase;font-weight:600;font-size:14px!important}.thpladmin-modal .wizard aside ul{margin:30px 0;padding:0}.thpladmin-modal .wizard aside li{cursor:pointer;list-style:none;padding:10px 24px;margin:4px 0;color:var(--primary-text-color);position:relative}.thpladmin-modal .wizard aside li.text-primary{color:var(--primary-text-color)}.thpladmin-modal .wizard aside li.active{background:var(--primary-bg-color);color:#fff}.thpladmin-modal .wizard aside li.disabled{display:none}.thpladmin-modal .wizard aside li .dashicons{margin-right:6px;line-height:18px;vertical-align:middle}.thpladmin-modal .wizard aside li.active .dashicons::before{color:#fff}.thpladmin-modal .wizard aside li i.i-chevron-right{font-style:normal;color:#fff;position:absolute;right:8px;font-family:dashicons;opacity:0;top:50%;transform:translate(-4px,-50%);transition:.35s}.thpladmin-modal .wizard aside li.active i.i-chevron-right{opacity:1}.thpladmin-modal .form-wizard main{left:0;right:0;padding:30px;position:absolute;bottom:80px;top:0;overflow:auto}.thpladmin-modal .wizard aside~footer,.thpladmin-modal .wizard aside~main{left:240px}.thpladmin-modal .form-wizard main.main-full{bottom:0}.thpladmin-modal .form-wizard main-title{display:block;margin-bottom:12px}.thpladmin-modal .form-wizard .device-mobile,.thwepo_pp_table tr.disabled.hide{display:none}.thpladmin-modal .form-wizard .device-desktop{display:inline}.thpladmin-modal .form-wizard footer{left:0;padding:10px 20px;right:0;background:#f6f6f6;border-top:1px solid #e0e0e0;bottom:0;position:absolute;text-align:right;z-index:99999999}.thpladmin-modal .form-wizard footer .Loader{float:left;opacity:0;transition:1s opacity;margin-top:4px;line-height:27px}.thpladmin-modal .form-wizard footer .btn-toolbar>.btn{margin-left:5px}.thpladmin-modal .form-wizard .form{margin-top:0;padding-bottom:0}.thpladmin-modal .form-wizard .data-panel-content{margin-top:30px;padding-bottom:90px}.thwepo_pp_table{width:100%}.thwepo_pp_table tr.disabled td.label,.thwepo_pp_table tr.disabled td.tip{opacity:.5}.thwepo_pp_table td{padding:5px 10px}.thwepo_pp_table.compact td{padding:3px 10px}.thwepo_pp_table td.h-separator{padding:20px 0!important}.thwepo_pp_table td.h-separator span{display:block;height:2px;border-top:1px dashed #e6e6e6}.thwepo_pp_table td.label{width:25%;text-align:right;padding-right:0;font-weight:700}.thwepo_pp_table td.tip{width:16px;text-align:center;padding:0}.thwepo_pp_table td.field{padding-left:0}.thwepo_pp_table input[type=text],.thwepo_pp_table input[type=number],.thwepo_pp_table select{width:260px}.thwepo_pp_table input[type=text].thwepo-color{width:223px;border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.thwepo_pp_table .thpladmin-colorpickpreview{padding:9.5px 15px 8.5px 20px;border:1px solid #e2e2e2;border-radius:2px 0 0 2px;border-right:1;background-color:#FFF}.thwepo_pp_table.thwepo-display-rules table{width:100%;padding:0;border-spacing:0;border-collapse:collapse}.thwepo_pp_table.thwepo-display-rules tr{vertical-align:top}.thwepo_pp_table.thwepo-display-rules td{padding:2px 0}.thwepo_pp_table.thwepo-display-rules .rule-action{width:80px}.thwepo-display-rules td.operand-type,.thwepo-display-rules td.operator{width:27%}.thwepo-display-rules td.actions{width:18%;padding-top:10px}.thpl_logic_link{background-color:var(--primary-bg-color);border-color:var(--primary-border-color)}.thwepo-display-rules .ajax-rules td.operand,.thwepo-display-rules .ajax-rules td.operator{width:27%}.thwepo-display-rules .ajax-rules td.value input[type=text],.thwepo-display-rules .ajax-rules td.value select,.thwepo-display-rules td.operand input[type=text],.thwepo-display-rules td.operand select,.thwepo-display-rules td.operand-type input[type=text],.thwepo-display-rules td.operand-type select,.thwepo-display-rules td.operator input[type=text],.thwepo-display-rules td.operator select{width:98%}.product_page_th_extra_product_options_pro .select2-container .select2-selection{border-radius:2px;border:1px solid #e2e2e2;min-height:36px;padding:0 4px}.thpladmin-options-table{width:100%;margin-bottom:30px}.thpladmin-options-table input[type=text],.thpladmin-options-table select{width:100%;padding:0 6px}.thpladmin-options-table td{padding:2px 0 2px 4px}.thpladmin-options-table td.price{width:70px}.thpladmin-options-table td.price-type{width:110px}.thpladmin-options-table td.action-cell{width:100px}.thpladmin-options-table td.action-cell .btn{margin-left:6px;padding:1px 5px 2px;font-size:18px;line-height:1}.thpladmin-options-table td.action-cell span.sort{cursor:move;font-size:18px;padding:0 1px 1px;border-color:#999}.thpladmin-options-table td.action-cell span.sort::before{content:'\f333';content:'\f228';font-family:Dashicons;text-align:center;vertical-align:middle;line-height:1;color:#999}.thwepo-settings-table{width:100%}.thwepo-settings-table td{padding:5px 0}.thwepo-settings-table td.section-title{padding:30px 0 5px;text-align:left;font-weight:700;text-transform:capitalize;border-bottom:1px dashed #cecece}.thwepo-settings-table td.label{width:22%;text-align:left;padding-right:0;font-weight:400}.thwepo-settings-table td.tip{width:16px;text-align:center;padding:0}.thwepo-settings-table td.field{padding-left:0}.thwepo-settings-table textarea{width:90%;font-size:.9em}
--------------------------------------------------------------------------------
/admin/class-thwepo-admin-form-section.php:
--------------------------------------------------------------------------------
1 | section_props = $this->get_section_form_props();
20 | }
21 |
22 | public function get_available_positions(){
23 | $positions = array(
24 | 'woo_before_add_to_cart_button' => 'Before Add To Cart Button',
25 | 'woo_after_add_to_cart_button' => 'After Add To Cart Button',
26 | 'woo_single_variation_5' => 'Before Variation Price (for variable products)',
27 | /*'woo_before_add_to_cart_quantity' => 'Before Add To Cart Quantity',
28 | 'woo_after_add_to_cart_quantity' => 'After Add To Cart Quantity',
29 | 'woo_before_variations_form' => 'Before Variations Form',
30 | 'woo_after_variations_form' => 'After Variations Form',
31 | 'woo_before_single_variation' => 'Before Single Variation',
32 | 'woo_after_single_variation' => 'After Single Variation',
33 | 'woo_single_variation_90' => 'woo_single_variation_90',
34 |
35 | 'woo_single_product_before_title' => 'Before Title',
36 | 'woo_single_product_after_title' => 'After Title',
37 | 'woo_single_product_before_rating' => 'Before Rating',
38 | 'woo_single_product_after_rating' => 'After Rating',
39 | 'woo_single_product_before_price' => 'Before Price',
40 | 'woo_single_product_after_price' => 'After Price',
41 | 'woo_single_product_before_excerpt' => 'Before Excerpt',
42 | 'woo_single_product_after_excerpt' => 'After Excerpt',
43 | 'woo_single_product_before_add_to_cart' => 'Before Add To Cart',
44 | 'woo_single_product_after_add_to_cart' => 'After Add To Cart',
45 | 'woo_single_product_before_meta' => 'Before Meta',
46 | 'woo_single_product_after_meta' => 'After Meta',
47 | 'woo_single_product_before_sharing' => 'Before Sharing',
48 | 'woo_single_product_after_sharing' => 'After Sharing',*/
49 | );
50 |
51 | if(apply_filters('thwepo_enable_additional_positions', false)){
52 | $positions['woo_before_variations_form'] = 'Before Variations Form';
53 | }
54 |
55 | return apply_filters('thwepo_extra_fields_display_position', $positions);
56 | }
57 |
58 | public function get_section_form_props(){
59 | $positions = $this->get_available_positions();
60 | $html_text_tags = $this->get_html_text_tags();
61 |
62 | /*$box_types = array(
63 | '' => 'Normal (clear)',
64 | 'box' => 'Box',
65 | 'collapse' => 'Expand and Collapse (start opened)',
66 | 'collapseclosed' => 'Expand and Collapse (start closed)',
67 | 'accordion' => 'Accordion',
68 | );*/
69 | //$title_positions = array( '' => 'Above field', 'left' => 'Left of the field', 'right' => 'Right of the field', 'disable' => 'Disable' );
70 |
71 | return array(
72 | 'name' => array('name'=>'name', 'label'=>'Name/ID', 'type'=>'text', 'required'=>1),
73 | 'position' => array('name'=>'position', 'label'=>'Display Position', 'type'=>'select', 'options'=>$positions, 'required'=>1),
74 | //'box_type' => array('name'=>'box_type', 'label'=>'Box Type', 'type'=>'select', 'options'=>$box_types),
75 | 'order' => array('name'=>'order', 'label'=>'Display Order', 'type'=>'text'),
76 | 'cssclass' => array('name'=>'cssclass', 'label'=>'CSS Class', 'type'=>'text'),
77 | 'show_title' => array('name'=>'show_title', 'label'=>'Show section title in product page.', 'type'=>'checkbox', 'value'=>'yes', 'checked'=>1),
78 |
79 | 'title_cell_with' => array('name'=>'title_cell_with', 'label'=>'Col-1 Width', 'type'=>'text', 'value'=>''),
80 | 'field_cell_with' => array('name'=>'field_cell_with', 'label'=>'Col-2 Width', 'type'=>'text', 'value'=>''),
81 |
82 | 'title' => array('name'=>'title', 'label'=>'Title', 'type'=>'text', 'required'=>1),
83 | //'title_position' => array('name'=>'title_position', 'label'=>'Title Position', 'type'=>'select', 'options'=>$title_positions),
84 | 'title_type' => array('name'=>'title_type', 'label'=>'Title Type', 'type'=>'select', 'value'=>'h3', 'options'=>$html_text_tags),
85 | 'title_color' => array('name'=>'title_color', 'label'=>'Title Color', 'type'=>'colorpicker'),
86 | 'title_class' => array('name'=>'title_class', 'label'=>'Title Class', 'type'=>'text'),
87 |
88 | 'subtitle' => array('name'=>'subtitle', 'label'=>'Subtitle', 'type'=>'text'),
89 | //'subtitle_position' => array('name'=>'subtitle_position', 'label'=>'Subtitle Position', 'type'=>'select', 'options'=>$title_positions),
90 | 'subtitle_type' => array('name'=>'subtitle_type', 'label'=>'Subtitle Type', 'type'=>'select', 'value'=>'h3', 'options'=>$html_text_tags),
91 | 'subtitle_color' => array('name'=>'subtitle_color', 'label'=>'Subtitle Color', 'type'=>'colorpicker'),
92 | 'subtitle_class' => array('name'=>'subtitle_class', 'label'=>'Subtitle Class', 'type'=>'text'),
93 | );
94 | }
95 |
96 | public function output_section_forms(){
97 | ?>
98 |
99 | output_popup_form_section(); ?>
100 |
101 |
110 |
179 | render_form_tab_main_title('Basic Details');
185 |
186 | ?>
187 |
188 |
189 |
190 | render_form_elm_row($this->section_props['name']);
192 | $this->render_form_elm_row($this->section_props['title']);
193 | $this->render_form_elm_row($this->section_props['subtitle']);
194 | $this->render_form_elm_row($this->section_props['position']);
195 | $this->render_form_elm_row($this->section_props['order']);
196 | $this->render_form_elm_row($this->section_props['title_cell_with']);
197 | $this->render_form_elm_row($this->section_props['field_cell_with']);
198 |
199 | $this->render_form_elm_row_cb($this->section_props['show_title']);
200 | ?>
201 |
202 |
203 | render_form_tab_main_title('Display Settings');
209 |
210 | ?>
211 |
212 |
213 | render_form_elm_row($this->section_props['cssclass']);
215 | $this->render_form_elm_row($this->section_props['title_class']);
216 | $this->render_form_elm_row($this->section_props['subtitle_class']);
217 |
218 | $this->render_form_elm_row($this->section_props['title_type']);
219 | $this->render_form_elm_row($this->section_props['title_color']);
220 | $this->render_form_elm_row($this->section_props['subtitle_type']);
221 | $this->render_form_elm_row($this->section_props['subtitle_color']);
222 | ?>
223 |
224 |
225 | render_form_tab_main_title('Display Rules');
231 |
232 | ?>
233 |
234 |
235 | render_form_fragment_rules('section');
237 | $this->render_form_fragment_rules_ajax('section');
238 | ?>
239 |
240 |
241 | render_form_tab_main_title('Repeat Rules');
247 |
248 | ?>
249 |
250 |
252 |
253 | data_prefix = str_ireplace( array( ' ', '_', '&', '?' ), '_', strtolower(THWEPO_SOFTWARE_TITLE) );
27 | $this->data_prefix = str_ireplace( 'woocommerce', 'th', $this->data_prefix );
28 | $this->ame_data_key = $this->data_prefix . '_data';
29 | $this->ame_deactivate_checkbox = $this->data_prefix . '_deactivate_checkbox';
30 | $this->ame_activation_tab_key = $this->data_prefix . '_license_activate';
31 | $this->ame_deactivation_tab_key = $this->data_prefix . '_license_deactivate';
32 | }
33 |
34 | public static function instance() {
35 | if(is_null(self::$_instance)){
36 | self::$_instance = new self();
37 | }
38 | return self::$_instance;
39 | }
40 |
41 | public function render_page(){
42 | settings_errors();
43 | $this->render_tabs();
44 | $this->render_content();
45 | }
46 |
47 | private function render_content(){
48 | echo do_shortcode('[licensepage_woocommerce_extra_product_options]');
49 | }
50 | }
51 |
52 | endif;
--------------------------------------------------------------------------------
/admin/class-thwepo-admin-settings.php:
--------------------------------------------------------------------------------
1 | page_id = $page;
24 | if($section){
25 | self::$section_id = $section;
26 | }else{
27 | self::set_first_section_as_current();
28 | }
29 | $this->tabs = array( 'general_settings' => 'Product Options', 'advanced_settings' => 'Advanced Settings', 'license_settings' => 'Plugin License');
30 | }
31 |
32 | public function get_tabs(){
33 | return $this->tabs;
34 | }
35 |
36 | public function get_current_tab(){
37 | return $this->page_id;
38 | }
39 |
40 | public function get_sections(){
41 | return $this->sections;
42 | }
43 |
44 | public function get_current_section(){
45 | return isset( $_GET['section'] ) ? esc_attr( $_GET['section'] ) : self::$section_id;
46 | }
47 |
48 | public static function set_current_section($section_id){
49 | if($section_id){
50 | self::$section_id = $section_id;
51 | }
52 | }
53 |
54 | public static function set_first_section_as_current(){
55 | $sections = THWEPO_Admin_Utils::get_sections();
56 | if($sections && is_array($sections)){
57 | $array_keys = array_keys( $sections );
58 | if($array_keys && is_array($array_keys) && isset($array_keys[0])){
59 | self::set_current_section($array_keys[0]);
60 | }
61 | }
62 | }
63 |
64 | public function render_tabs(){
65 | $current_tab = $this->get_current_tab();
66 | $tabs = $this->get_tabs();
67 |
68 | if(empty($tabs)){
69 | return;
70 | }
71 |
72 | echo '';
73 | foreach( $tabs as $id => $label ){
74 | $active = ( $current_tab == $id ) ? 'nav-tab-active' : '';
75 | $label = THWEPO_i18n::__t($label);
76 | echo ''.$label.'';
77 | }
78 | echo '
';
79 | }
80 |
81 | public function render_sections() {
82 | $current_section = $this->get_current_section();
83 | $sections = $this->get_sections();
84 |
85 | if(empty($sections)){
86 | return;
87 | }
88 |
89 | $array_keys = array_keys( $sections );
90 | $section_html = '';
91 |
92 | foreach( $sections as $id => $label ){
93 | $label = THWEPO_i18n::__t($label);
94 | $url = $this->get_admin_url($this->page_id, sanitize_title($id));
95 | $section_html .= ''.$label.' '.(end($array_keys) == $id ? '' : '|').' ';
96 | }
97 |
98 | if($section_html){
99 | echo '';
100 | echo $section_html;
101 | echo '
';
102 | }
103 | }
104 |
105 | public function get_admin_url($tab = false, $section = false){
106 | $url = 'edit.php?post_type=product&page=th_extra_product_options_pro';
107 | if($tab && !empty($tab)){
108 | $url .= '&tab='. $tab;
109 | }
110 | if($section && !empty($section)){
111 | $url .= '§ion='. $section;
112 | }
113 | return admin_url($url);
114 | }
115 |
116 | public function print_notices($msg, $type='updated', $return=false){
117 | $notice = ''. THWEPO_i18n::__t($msg) .'
';
118 | if(!$return){
119 | echo $notice;
120 | }
121 | return $notice;
122 | }
123 |
124 | public function render_form_field_element($field, $atts = array(), $render_cell = true){
125 | if($field && is_array($field)){
126 | $args = shortcode_atts( array(
127 | 'label_cell_props' => '',
128 | 'input_cell_props' => '',
129 | 'label_cell_colspan' => '',
130 | 'input_cell_colspan' => '',
131 | ), $atts );
132 |
133 | $ftype = isset($field['type']) ? $field['type'] : 'text';
134 | $flabel = isset($field['label']) && !empty($field['label']) ? THWEPO_i18n::__t($field['label']) : '';
135 | $sub_label = isset($field['sub_label']) && !empty($field['sub_label']) ? THWEPO_i18n::__t($field['sub_label']) : '';
136 | $tooltip = isset($field['hint_text']) && !empty($field['hint_text']) ? THWEPO_i18n::__t($field['hint_text']) : '';
137 |
138 | $field_html = '';
139 |
140 | if($ftype == 'text'){
141 | $field_html = $this->render_form_field_element_inputtext($field, $atts);
142 |
143 | }else if($ftype == 'textarea'){
144 | $field_html = $this->render_form_field_element_textarea($field, $atts);
145 |
146 | }else if($ftype == 'select'){
147 | $field_html = $this->render_form_field_element_select($field, $atts);
148 |
149 | }else if($ftype == 'multiselect'){
150 | $field_html = $this->render_form_field_element_multiselect($field, $atts);
151 |
152 | }else if($ftype == 'colorpicker'){
153 | $field_html = $this->render_form_field_element_colorpicker($field, $atts);
154 |
155 | }else if($ftype == 'checkbox'){
156 | $field_html = $this->render_form_field_element_checkbox($field, $atts, $render_cell);
157 | $flabel = ' ';
158 | }
159 |
160 | if($render_cell){
161 | $required_html = isset($field['required']) && $field['required'] ? '*' : '';
162 |
163 | $label_cell_props = !empty($args['label_cell_props']) ? $args['label_cell_props'] : '';
164 | $input_cell_props = !empty($args['input_cell_props']) ? $args['input_cell_props'] : '';
165 |
166 | ?>
167 | >
168 |
171 |
172 |
175 | |
176 | render_form_fragment_tooltip($tooltip); ?>
177 | > |
178 | '',
189 | 'input_name_prefix' => 'i_',
190 | 'input_name_suffix' => '',
191 | ), $atts );
192 |
193 | $ftype = isset($field['type']) ? $field['type'] : 'text';
194 |
195 | $input_class = '';
196 | if($ftype == 'text'){
197 | $input_class = 'thwepo-inputtext';
198 | }else if($ftype == 'select'){
199 | $input_class = 'thwepo-select';
200 | }else if($ftype == 'multiselect'){
201 | $input_class = 'thwepo-select thwepo-enhanced-multi-select';
202 | }else if($ftype == 'colorpicker'){
203 | $input_class = 'thwepo-color thpladmin-colorpick';
204 | }
205 |
206 | if($ftype == 'multiselect'){
207 | $args['input_name_suffix'] = $args['input_name_suffix'].'[]';
208 | }
209 |
210 | $fname = $args['input_name_prefix'].$field['name'].$args['input_name_suffix'];
211 | $fvalue = isset($field['value']) ? esc_html($field['value']) : '';
212 |
213 | $input_width = $args['input_width'] ? 'width:'.$args['input_width'].';' : '';
214 | $field_props = 'name="'. $fname .'" style="'. $input_width .'"';
215 | $field_props .= !empty($input_class) ? ' class="'. $input_class .'"' : '';
216 | $field_props .= $ftype == 'textarea' ? '' : ' value="'. $fvalue .'"';
217 | $field_props .= ( isset($field['placeholder']) && !empty($field['placeholder']) ) ? ' placeholder="'.$field['placeholder'].'"' : '';
218 | $field_props .= ( isset($field['onchange']) && !empty($field['onchange']) ) ? ' onchange="'.$field['onchange'].'"' : '';
219 |
220 | return $field_props;
221 | }
222 |
223 | private function render_form_field_element_inputtext($field, $atts = array()){
224 | $field_html = '';
225 | if($field && is_array($field)){
226 | $field_props = $this->prepare_form_field_props($field, $atts);
227 | $field_html = '';
228 | }
229 | return $field_html;
230 | }
231 |
232 | private function render_form_field_element_textarea($field, $atts = array()){
233 | $field_html = '';
234 | if($field && is_array($field)){
235 | $args = shortcode_atts( array(
236 | 'rows' => '5',
237 | 'cols' => '100',
238 | ), $atts );
239 |
240 | $fvalue = isset($field['value']) ? $field['value'] : '';
241 | $field_props = $this->prepare_form_field_props($field, $atts);
242 | $field_html = '';
243 | }
244 | return $field_html;
245 | }
246 |
247 | private function render_form_field_element_select($field, $atts = array()){
248 | $field_html = '';
249 | if($field && is_array($field)){
250 | $fvalue = isset($field['value']) ? $field['value'] : '';
251 | $field_props = $this->prepare_form_field_props($field, $atts);
252 |
253 | $field_html = '';
259 | }
260 | return $field_html;
261 | }
262 |
263 | private function render_form_field_element_multiselect($field, $atts = array()){
264 | $field_html = '';
265 | if($field && is_array($field)){
266 | $field_props = $this->prepare_form_field_props($field, $atts);
267 |
268 | $field_html = '';
274 | }
275 | return $field_html;
276 | }
277 |
278 | private function render_form_field_element_radio($field, $atts = array()){
279 | $field_html = '';
280 | /*if($field && is_array($field)){
281 | $field_props = $this->prepare_form_field_props($field, $atts);
282 |
283 | $field_html = '';
289 | }*/
290 | return $field_html;
291 | }
292 |
293 | private function render_form_field_element_checkbox($field, $atts = array(), $render_cell = true){
294 | $field_html = '';
295 | if($field && is_array($field)){
296 | $args = shortcode_atts( array(
297 | 'label_props' => '',
298 | 'cell_props' => 3,
299 | 'render_input_cell' => false,
300 | ), $atts );
301 |
302 | $fid = 'a_f'. $field['name'];
303 | $flabel = isset($field['label']) && !empty($field['label']) ? THWEPO_i18n::__t($field['label']) : '';
304 |
305 | $field_props = $this->prepare_form_field_props($field, $atts);
306 | $field_props .= isset($field['checked']) && $field['checked'] === 1 ? ' checked' : '';
307 |
308 | $field_html = '';
309 | $field_html .= '';
310 | }
311 | if(!$render_cell && $args['render_input_cell']){
312 | return ''. $field_html .' | ';
313 | }else{
314 | return $field_html;
315 | }
316 | }
317 |
318 | private function render_form_field_element_colorpicker($field, $atts = array()){
319 | $field_html = '';
320 | if($field && is_array($field)){
321 | $field_props = $this->prepare_form_field_props($field, $atts);
322 |
323 | $field_html = '';
324 | $field_html .= '';
325 | }
326 | return $field_html;
327 | }
328 |
329 | public function render_form_fragment_tooltip($tooltip = false){
330 | if($tooltip){
331 | ?>
332 |
333 |
334 | |
335 |
338 | |
339 | 6,
346 | 'padding-top' => '5px',
347 | 'border-style' => 'dashed',
348 | 'border-width' => '1px',
349 | 'border-color' => '#e6e6e6',
350 | 'content' => '',
351 | ), $atts );
352 |
353 | $style = $args['padding-top'] ? 'padding-top:'.$args['padding-top'].';' : '';
354 | $style .= $args['border-style'] ? ' border-bottom:'.$args['border-width'].' '.$args['border-style'].' '.$args['border-color'].';' : '';
355 |
356 | ?>
357 | |
358 | | ';
364 | }*/
365 |
366 | public function render_field_form_fragment_h_spacing($padding = 5){
367 | $style = $padding ? 'padding-top:'.$padding.'px;' : '';
368 | ?>
369 | |
370 |
375 | |
376 |
381 | |
382 | |
383 | |
384 | get_property('name')] = $section;
26 | return $sections;
27 | }
28 | }
29 |
30 | public static function get_section($section_name){
31 | if($section_name){
32 | $sections = self::get_sections();
33 | if(is_array($sections) && isset($sections[$section_name])){
34 | $section = $sections[$section_name];
35 | if(THWEPO_Utils_Section::is_valid_section($section)){
36 | return $section;
37 | }
38 | }
39 | }
40 | return false;
41 | }
42 |
43 | //Example function to move fields from one section to another.
44 | public static function copy_fields_from_one_to_another($from, $to, $fields){
45 | if(is_array($fields) && !empty($fields) && $from && $to){
46 | $sections = THWEPO_Utils::get_custom_sections();
47 |
48 | if(is_array($sections) && isset($sections[$from]) && isset($sections[$to])){
49 | $section_from = $sections[$from];
50 | $section_to = $sections[$to];
51 |
52 | if(THWEPO_Utils_Section::is_valid_section($section_from) && THWEPO_Utils_Section::is_valid_section($section_to)){
53 | $update_flag = false;
54 | $field_set_from = THWEPO_Utils_Section::get_fields($section_from);
55 | $field_set_to = THWEPO_Utils_Section::get_fields($section_to);
56 |
57 | foreach($fields as $fname){
58 | if(!isset($field_set_to[$fname])){
59 | $field = $field_set_from[$fname];
60 | $section_to = THWEPO_Utils_Section::add_field($section_to, $field);
61 | $update_flag = true;
62 | }
63 | }
64 |
65 | if($update_flag){
66 | $sections[$to] = $section_to;
67 | $result = update_option(THWEPO_Utils::OPTION_KEY_CUSTOM_SECTIONS, $sections);
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
74 | public static function skip_products_loading(){
75 | $skip = apply_filters('thwepo_disable_product_dropdown', false);
76 | return $skip;
77 | }
78 |
79 | public static function load_products($only_id = false){
80 | $productsList = array();
81 | $skip = self::skip_products_loading();
82 |
83 | if(!$skip){
84 | $limit = apply_filters('thwepo_load_products_per_page', -1);
85 | $only_id = apply_filters('thwepo_load_products_id_only', $only_id);
86 | $status = apply_filters('thwepo_load_products_status', 'publish');
87 |
88 | $args = array('status' => $status, 'limit' => $limit, 'orderby' => 'name', 'order' => 'ASC', 'return' => 'ids');
89 |
90 | $products = wc_get_products( $args );
91 |
92 | if(count($products) > 0){
93 | if($only_id){
94 | return $products;
95 | }else{
96 | foreach($products as $pid){
97 | //$productsList[] = array("id" => $product->ID, "title" => $product->post_title);
98 | $productsList[] = array("id" => $pid, "title" => get_the_title($pid));
99 | }
100 | }
101 | }
102 | }
103 | return $productsList;
104 | }
105 |
106 | /*public static function load_products($only_id = false){
107 | $productsList = array();
108 | $skip = self::skip_products_loading();
109 |
110 | if(!$skip){
111 | $posts_per_page = apply_filters('thwepo_load_products_per_page', -1);
112 | $only_id = apply_filters('thwepo_load_products_id_only', $only_id);
113 | $args = array( 'post_type' => 'product', 'order' => 'ASC', 'posts_per_page' => $posts_per_page, 'fields' => 'ids' );
114 |
115 | $products = get_posts( $args );
116 |
117 | if(count($products) > 0){
118 | if($only_id){
119 | return $products;
120 | }else{
121 | foreach($products as $pid){
122 | //$productsList[] = array("id" => $product->ID, "title" => $product->post_title);
123 | $productsList[] = array("id" => $pid, "title" => get_the_title($pid));
124 | }
125 | }
126 | }
127 | }
128 | return $productsList;
129 | }*/
130 |
131 | /*public static function load_products(){
132 | $args = array( 'post_type' => 'product', 'order' => 'ASC', 'posts_per_page' => -1, 'fields' => 'ids' );
133 | $products = get_posts( $args );
134 | $productsList = array();
135 |
136 | if(count($products) > 0){
137 | foreach($products as $pid){
138 | //$productsList[] = array("id" => $product->ID, "title" => $product->post_title);
139 | $productsList[] = array("id" => $pid, "title" => get_the_title($pid));
140 | }
141 | }
142 | return $productsList;
143 | }*/
144 |
145 | /*public static function load_products_cat(){
146 | $ignore_translation = apply_filters('thwepo_ignore_wpml_translation_for_product_category', true);
147 | $is_wpml_active = THWEPO_Utils::is_wpml_active();
148 |
149 | $product_cat = array();
150 | $pcat_terms = get_terms('product_cat', 'orderby=count&hide_empty=0');
151 |
152 | foreach($pcat_terms as $pterm){
153 | $pcat_slug = $pterm->slug;
154 | $pcat_slug = THWEPO_Utils::check_for_wpml_traslation($pcat_slug, $pterm, $is_wpml_active, $ignore_translation);
155 |
156 | $product_cat[] = array("id" => $pcat_slug, "title" => $pterm->name);
157 | }
158 | return $product_cat;
159 | }*/
160 |
161 | public static function load_products_cat($only_slug = false){
162 | $product_cats = self::load_product_terms('category', 'product_cat', $only_slug);
163 | return $product_cats;
164 | }
165 |
166 | public static function load_product_tags($only_slug = false){
167 | $product_tags = self::load_product_terms('tag', 'product_tag', $only_slug);
168 | return $product_tags;
169 | }
170 |
171 | public static function load_product_terms($type, $taxonomy, $only_slug = false){
172 | $product_terms = array();
173 | $pterms = get_terms($taxonomy, 'orderby=count&hide_empty=0');
174 |
175 | $ignore_translation = true;
176 | $is_wpml_active = THWEPO_Utils::is_wpml_active();
177 | if($is_wpml_active && $ignore_translation){
178 | /*global $sitepress;
179 | global $icl_adjust_id_url_filter_off;
180 | $orig_flag_value = $icl_adjust_id_url_filter_off;
181 | $icl_adjust_id_url_filter_off = true;
182 | $default_lang = $sitepress->get_default_language();*/
183 | $default_lang = THWEPO_Utils::off_wpml_translation();
184 | }
185 |
186 | if(is_array($pterms)){
187 | foreach($pterms as $term){
188 | $dterm = $term;
189 |
190 | if($is_wpml_active && $ignore_translation){
191 | //$def_term_id = icl_object_id($term->term_id, $type, true, $default_lang);
192 | //$def_term = get_term($def_term_id);
193 | $dterm = THWEPO_Utils::get_default_lang_term($term, $taxonomy, $default_lang);
194 | }
195 |
196 | if($only_slug){
197 | $product_terms[] = $dterm->slug;
198 | }else{
199 | $product_terms[] = array("id" => $dterm->slug, "title" => $dterm->name);
200 | }
201 | }
202 | }
203 |
204 | if($is_wpml_active && $ignore_translation){
205 | //$icl_adjust_id_url_filter_off = $orig_flag_value;
206 | THWEPO_Utils::may_on_wpml_translation($default_lang);
207 | }
208 |
209 | return $product_terms;
210 | }
211 |
212 | public static function load_user_roles(){
213 | $user_roles = array();
214 |
215 | global $wp_roles;
216 | $roles = $wp_roles->roles;
217 | //$roles = get_editable_roles();
218 | foreach($roles as $key => $role){
219 | $user_roles[] = array("id" => $key, "title" => $role['name']);
220 | }
221 |
222 | return $user_roles;
223 | }
224 |
225 | public static function sort_sections_by_order($a, $b){
226 | if(is_array($a) && is_array($b)){
227 | $order_a = isset($a['order']) && is_numeric($a['order']) ? $a['order'] : 0;
228 | $order_b = isset($b['order']) && is_numeric($b['order']) ? $b['order'] : 0;
229 |
230 | if($order_a == $order_b){
231 | return 0;
232 | }
233 | return ($order_a < $order_b) ? -1 : 1;
234 | }else if(THWEPO_Utils_Section::is_valid_section($a) && THWEPO_Utils_Section::is_valid_section($b)){
235 | $order_a = is_numeric($a->get_property('order')) ? $a->get_property('order') : 0;
236 | $order_b = is_numeric($b->get_property('order')) ? $b->get_property('order') : 0;
237 |
238 | if($order_a == $order_b){
239 | return 0;
240 | }
241 | return ($order_a < $order_b) ? -1 : 1;
242 | }else{
243 | return 0;
244 | }
245 | }
246 |
247 | public static function stable_uasort(&$array, $cmp_function) {
248 | if(count($array) < 2) {
249 | return;
250 | }
251 |
252 | $halfway = count($array) / 2;
253 | $array1 = array_slice($array, 0, $halfway, TRUE);
254 | $array2 = array_slice($array, $halfway, NULL, TRUE);
255 |
256 | self::stable_uasort($array1, $cmp_function);
257 | self::stable_uasort($array2, $cmp_function);
258 | if(call_user_func_array($cmp_function, array(end($array1), reset($array2))) < 1) {
259 | $array = $array1 + $array2;
260 | return;
261 | }
262 |
263 | $array = array();
264 | reset($array1);
265 | reset($array2);
266 | while(current($array1) && current($array2)) {
267 | if(call_user_func_array($cmp_function, array(current($array1), current($array2))) < 1) {
268 | $array[key($array1)] = current($array1);
269 | next($array1);
270 | } else {
271 | $array[key($array2)] = current($array2);
272 | next($array2);
273 | }
274 | }
275 | while(current($array1)) {
276 | $array[key($array1)] = current($array1);
277 | next($array1);
278 | }
279 | while(current($array2)) {
280 | $array[key($array2)] = current($array2);
281 | next($array2);
282 | }
283 | return;
284 | }
285 | }
286 |
287 | endif;
--------------------------------------------------------------------------------
/admin/class-thwepo-admin.php:
--------------------------------------------------------------------------------
1 | plugin_name = $plugin_name;
28 | $this->version = $version;
29 |
30 | //$this->init_product_settings();
31 | }
32 |
33 | public function enqueue_styles_and_scripts($hook) {
34 | if(strpos($hook, 'product_page_th_extra_product_options_pro') === false) {
35 | return;
36 | }
37 | $debug_mode = apply_filters('thwepo_debug_mode', false);
38 | $suffix = $debug_mode ? '' : '.min';
39 |
40 | $this->enqueue_styles($suffix);
41 | $this->enqueue_scripts($suffix);
42 | }
43 |
44 | private function enqueue_styles($suffix) {
45 | wp_enqueue_style('jquery-ui-style', '//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css?ver=1.11.4');
46 | wp_enqueue_style('woocommerce_admin_styles', THWEPO_WOO_ASSETS_URL.'css/admin.css');
47 | wp_enqueue_style('wp-color-picker');
48 | wp_enqueue_style('thwepo-admin-style', THWEPO_ASSETS_URL_ADMIN . 'css/thwepo-admin'. $suffix .'.css', $this->version);
49 | //wp_enqueue_style('thwepo-colorpicker-style', THWEPO_ASSETS_URL_ADMIN . 'colorpicker/spectrum.css');
50 | }
51 |
52 | private function enqueue_scripts($suffix) {
53 | $deps = array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-tiptip', 'wc-enhanced-select', 'selectWoo', 'wp-color-picker');
54 | //$deps = array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-tiptip', 'woocommerce_admin', 'wc-enhanced-select', 'selectWoo', 'wp-color-picker');
55 |
56 | /*wp_enqueue_script('thwepo-admin-base', THWEPO_ASSETS_URL_ADMIN . 'js/inc/thwepo-admin-base.js', $deps, $this->version, false);
57 | wp_enqueue_script('thwepo-admin-conditions', THWEPO_ASSETS_URL_ADMIN . 'js/inc/thwepo-admin-conditions.js', array('thwepo-admin-base'), $this->version, false);
58 | wp_enqueue_script('thwepo-admin-script', THWEPO_ASSETS_URL_ADMIN . 'js/inc/thwepo-admin.js', array('thwepo-admin-base', 'thwepo-admin-conditions'), $this->version, false);
59 | wp_enqueue_script('thwepo-admin-conditions', THWEPO_ASSETS_URL_ADMIN . 'js/inc/thwepo-admin-advanced.js', array('thwepo-admin-base'), $this->version, false);
60 | */
61 | wp_enqueue_script( 'thwepo-admin-script', THWEPO_ASSETS_URL_ADMIN . 'js/thwepo-admin'. $suffix .'.js', $deps, $this->version, false );
62 |
63 | $wepo_var = array(
64 | 'admin_url' => admin_url(),
65 | 'ajax_url' => admin_url( 'admin-ajax.php' ),
66 | );
67 | wp_localize_script('thwepo-admin-script', 'wepo_var', $wepo_var);
68 | }
69 |
70 | public function wepo_capability() {
71 | $allowed = array('manage_woocommerce', 'manage_options');
72 | $capability = apply_filters('thwepo_required_capability', 'manage_woocommerce');
73 |
74 | if(!in_array($capability, $allowed)){
75 | $capability = 'manage_woocommerce';
76 | }
77 | return $capability;
78 | }
79 |
80 | public function admin_menu() {
81 | $capability = $this->wepo_capability();
82 | $this->screen_id = add_submenu_page('edit.php?post_type=product', THWEPO_i18n::__t('WooCommerce Extra Product Option'),
83 | THWEPO_i18n::__t('Live Preview'), $capability, 'th_extra_product_options_pro', array($this, 'output_settings'));
84 |
85 | //add_action('admin_print_scripts-'. $this->screen_id, array($this, 'enqueue_admin_scripts'));
86 | }
87 |
88 | public function add_screen_id($ids){
89 | $ids[] = 'woocommerce_page_th_extra_product_options_pro';
90 | $ids[] = strtolower( THWEPO_i18n::__t('WooCommerce') ) .'_page_th_extra_product_options_pro';
91 |
92 | return $ids;
93 | }
94 |
95 | /*public function init_product_settings(){
96 | $prod_settings = THWEPO_Admin_Settings_Product::instance();
97 | $prod_settings->render_page();
98 | }*/
99 |
100 | public function plugin_action_links($links) {
101 | $settings_link = ''. __('Settings') .'';
102 | array_unshift($links, $settings_link);
103 | return $links;
104 | }
105 |
106 | public function plugin_row_meta( $links, $file ) {
107 | if(THWEPO_BASE_NAME == $file) {
108 | $doc_link = esc_url('https://www.themehigh.com/help-guides/woocommerce-extra-product-options/');
109 | $support_link = esc_url('https://www.themehigh.com/help-guides/');
110 |
111 | $row_meta = array(
112 | 'docs' => ''.THWEPO_i18n::esc_html__t('Docs').'',
113 | 'support' => ''. THWEPO_i18n::esc_html__t('Premium support') .'',
114 | );
115 |
116 | return array_merge( $links, $row_meta );
117 | }
118 | return (array) $links;
119 | }
120 |
121 | public function output_settings(){
122 | $tab = isset( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'general_settings';
123 |
124 | echo '';
125 | if($tab === 'advanced_settings'){
126 | $advanced_settings = THWEPO_Admin_Settings_Advanced::instance();
127 | $advanced_settings->render_page();
128 | }else if($tab === 'license_settings'){
129 | $license_settings = THWEPO_Admin_Settings_License::instance();
130 | $license_settings->render_page();
131 | }else{
132 | $general_settings = THWEPO_Admin_Settings_General::instance();
133 | $general_settings->render_page();
134 | }
135 | echo '
';
136 | }
137 | }
138 |
139 | endif;
--------------------------------------------------------------------------------
/admin/index.php:
--------------------------------------------------------------------------------
1 | = 2.0){
45 | self::may_copy_free_version_settings_200();
46 | }else{
47 | self::may_copy_free_version_settings_134();
48 | }
49 | }
50 |
51 | /***********************************************
52 | ****** Copy Setting from version < 2.0.0 ******
53 | ***********************************************/
54 | public static function may_copy_free_version_settings_134(){
55 | $extra_options = get_option('thwepof_custom_product_fields');
56 |
57 | if($extra_options && is_array($extra_options)){
58 | $section = THWEPO_Utils_Section::prepare_default_section();
59 | $section = self::prepare_section_and_fields_134($section, $extra_options);
60 | $section = THWEPO_Utils_Section::sort_fields($section);
61 |
62 | $general_settings = new THWEPO_Admin_Settings_General();
63 | $result1 = $general_settings->update_section($section);
64 | $result2 = $general_settings->update_options_name_title_map();
65 |
66 | delete_option('thwepof_custom_product_fields');
67 | }
68 | }
69 |
70 | public static function prepare_section_and_fields_134($section, $extra_options){
71 | foreach($extra_options as $hook => $fields){
72 | if($fields){
73 | foreach($fields as $field_name => $field){
74 | try{
75 | $new_field = self::prepare_fields_134($field);
76 | $section = THWEPO_Utils_Section::add_field($section, $new_field);
77 | } catch (Exception $e) {
78 | }
79 | }
80 | }
81 | }
82 | return $section;
83 | }
84 |
85 | public static function prepare_fields_134($field){
86 | $new_field = false;
87 |
88 | if($field){
89 | $type = $field->get_property('type');
90 | $order = $field->get_property('order');
91 | $id = $field->get_property('id');
92 | $name = $field->get_property('name');
93 | $value = $field->get_property('value');
94 | $placeholder = $field->get_property('placeholder');
95 | $validate = $field->get_property('validator');
96 | $cssclass = $field->get_property('cssclass');
97 | $title = $field->get_property('title');
98 | $title_position = $field->get_property('title_position');
99 | $title_class = $field->get_property('title_class');
100 | $cols = $field->get_property('cols');
101 | $rows = $field->get_property('rows');
102 | $checked = $field->get_property('checked');
103 | $required = $field->is_required();
104 | $enabled = $field->is_enabled();
105 | $conditional_rules = $field->get_property('conditional_rules');
106 |
107 | $new_field = THWEPO_Utils_Field::create_field($type);
108 | $new_field->set_property('order', $order);
109 | $new_field->set_property('id', $id);
110 | $new_field->set_property('name', $name);
111 | $new_field->set_property('value', $value);
112 | $new_field->set_property('placeholder', $placeholder);
113 | $new_field->set_property('validate', $validate);
114 | $new_field->set_property('cssclass', $cssclass);
115 | $new_field->set_property('title', $title);
116 | $new_field->set_property('title_position', $title_position);
117 | $new_field->set_property('title_type', 'label');
118 | $new_field->set_property('title_class', $title_class);
119 | $new_field->set_property('cols', $cols);
120 | $new_field->set_property('rows', $rows);
121 | $new_field->set_property('checked', $checked);
122 | $new_field->set_property('required', $required);
123 | $new_field->set_property('enabled', $enabled);
124 |
125 | if($type === 'select' || $type === 'radio'){
126 | $new_options = array();
127 |
128 | $options = $field->get_property('options');
129 | if($options && is_array($options)){
130 | foreach($options as $option){
131 | $new_option = array();
132 | $new_option['key'] = $option;
133 | $new_option['text'] = $option;
134 | $new_option['price'] = '';
135 | $new_option['price_type'] = '';
136 |
137 | $new_options[$option] = $new_option;
138 | }
139 | }
140 |
141 | $new_options_json = json_encode($new_options);
142 | $new_options_json = rawurlencode($new_options_json);
143 | $new_options_json = trim(stripslashes($new_options_json));
144 |
145 | $new_field->set_property('options', $new_options);
146 | $new_field->set_property('options_json', $new_options_json);
147 | }
148 |
149 | $new_field = self::prepare_conditional_rules($new_field, $conditional_rules);
150 | $new_field = THWEPO_Utils_Field::prepare_properties($new_field);
151 | }
152 | return $new_field;
153 | }
154 |
155 | /***********************************************
156 | ****** Copy Setting from version >= 2.0.0 *****
157 | ***********************************************/
158 | public static function may_copy_free_version_settings_200(){
159 | if(class_exists('THWEPOF_Section') && class_exists('WEPOF_Product_Field')){
160 | $custom_sections = get_option('thwepof_custom_sections');
161 |
162 | if(is_array($custom_sections)){
163 | $advanced_settings = get_option('thwepof_advanced_settings');
164 | $general_settings = new THWEPO_Admin_Settings_General();
165 | $result = true;
166 |
167 | foreach($custom_sections as $key => $sectionf){
168 | $section = self::prepare_section_200($sectionf, $advanced_settings);
169 | if($section){
170 | $result1 = $general_settings->update_section($section);
171 | $result2 = $general_settings->update_options_name_title_map();
172 |
173 | if(!$result1 || !$result2){
174 | $result = false;
175 | }
176 | }
177 | }
178 |
179 | if($result){
180 | //delete_option('thwepof_custom_sections');
181 | //delete_option('thwepof_section_hook_map');
182 | //delete_option('thwepof_options_name_title_map');
183 | }
184 | }
185 | }
186 |
187 | self::may_copy_advanced_settings();
188 | }
189 |
190 | public static function prepare_section_200($sectionf, $advanced_settings=array()){
191 | try{
192 | if($sectionf instanceof THWEPOF_Section){
193 | $section = new WEPO_Product_Page_Section();
194 | $section->set_property('id', $sectionf->get_property('id'));
195 | $section->set_property('name', $sectionf->get_property('name'));
196 | $section->set_property('title', $sectionf->get_property('title'));
197 | $section->set_property('show_title', $sectionf->get_property('show_title'));
198 | $section->set_property('position', $sectionf->get_property('position'));
199 |
200 | $fields = $sectionf->get_property('fields');
201 | if(is_array($fields)){
202 | $hide_in_cart = isset($advanced_settings['hide_in_cart']) ? $advanced_settings['hide_in_cart'] : false;
203 | $hide_in_order = isset($advanced_settings['hide_in_order']) ? $advanced_settings['hide_in_order'] : false;
204 | $hide_in_checkout = isset($advanced_settings['hide_in_checkout']) ? $advanced_settings['hide_in_checkout'] : false;
205 |
206 | foreach($fields as $key => $fieldf){
207 | $field = self::prepare_field_200($fieldf);
208 | if($field){
209 | $field->set_property('hide_in_cart', $hide_in_cart);
210 | $field->set_property('hide_in_order', $hide_in_order);
211 | $field->set_property('hide_in_checkout', $hide_in_checkout);
212 |
213 | $section = THWEPO_Utils_Section::add_field($section, $field);
214 | }
215 | }
216 | $section = THWEPO_Utils_Section::sort_fields($section);
217 | }
218 |
219 | $conditional_rules = $sectionf->get_property('conditional_rules');
220 | $section = self::prepare_conditional_rules($section, $conditional_rules);
221 |
222 | return $section;
223 | }
224 | }catch (Exception $e) {
225 | return false;
226 | }
227 | return false;
228 | }
229 |
230 | public static function prepare_field_200($field){
231 | $new_field = false;
232 |
233 | if($field instanceof WEPOF_Product_Field){
234 | $type = $field->get_property('type');
235 | $order = $field->get_property('order');
236 | $id = $field->get_property('id');
237 | $name = $field->get_property('name');
238 | $value = $field->get_property('value');
239 | $placeholder = $field->get_property('placeholder');
240 | $validate = $field->get_property('validator');
241 | $cssclass = $field->get_property('cssclass');
242 | $title = $field->get_property('title');
243 | $title_position = $field->get_property('title_position');
244 | $title_class = $field->get_property('title_class');
245 | $cols = $field->get_property('cols');
246 | $rows = $field->get_property('rows');
247 | $checked = $field->get_property('checked');
248 | $required = $field->is_required();
249 | $enabled = $field->is_enabled();
250 | $readonly = $field->is_readonly();
251 | $conditional_rules = $field->get_property('conditional_rules');
252 |
253 | $type = $type === 'paragraph' ? 'label' : $type;
254 |
255 | $new_field = THWEPO_Utils_Field::create_field($type);
256 | $new_field->set_property('order', $order);
257 | $new_field->set_property('id', $id);
258 | $new_field->set_property('name', $name);
259 | $new_field->set_property('value', $value);
260 | $new_field->set_property('placeholder', $placeholder);
261 | $new_field->set_property('validate', $validate);
262 | $new_field->set_property('cssclass', $cssclass);
263 | $new_field->set_property('title', $title);
264 | $new_field->set_property('title_position', $title_position);
265 | $new_field->set_property('title_type', 'label');
266 | $new_field->set_property('title_class', $title_class);
267 | $new_field->set_property('cols', $cols);
268 | $new_field->set_property('rows', $rows);
269 | $new_field->set_property('checked', $checked);
270 | $new_field->set_property('required', $required);
271 | $new_field->set_property('enabled', $enabled);
272 | $new_field->set_property('readonly', $readonly);
273 |
274 | if($type === 'select' || $type === 'radio' || $type === 'checkboxgroup'){
275 | $new_options = array();
276 |
277 | $options = $field->get_property('options');
278 | if($options && is_array($options)){
279 | foreach($options as $option){
280 | $new_option = array();
281 | $new_option['key'] = $option;
282 | $new_option['text'] = $option;
283 | $new_option['price'] = '';
284 | $new_option['price_type'] = '';
285 |
286 | $new_options[$option] = $new_option;
287 | }
288 | }
289 |
290 | $new_options_json = json_encode($new_options);
291 | $new_options_json = rawurlencode($new_options_json);
292 | $new_options_json = trim(stripslashes($new_options_json));
293 |
294 | $new_field->set_property('options', $new_options);
295 | $new_field->set_property('options_json', $new_options_json);
296 |
297 | }else if($type === 'datepicker'){
298 | $new_field->set_property('default_date', $value);
299 |
300 | }else if($type === 'heading' || $type === 'label'){
301 | $new_field->set_property('title', $value);
302 | $new_field->set_property('title_class', $cssclass);
303 | }
304 |
305 | $new_field = self::prepare_conditional_rules($new_field, $conditional_rules);
306 | $new_field = THWEPO_Utils_Field::prepare_properties($new_field);
307 | }
308 | return $new_field;
309 | }
310 |
311 | public static function prepare_conditional_rules($object, $conditional_rules){
312 | $new_condition_rule_sets = array();
313 | $cr_sets = array();
314 |
315 | if($conditional_rules && is_array($conditional_rules)){
316 | foreach($conditional_rules as $rule_set){
317 | if($rule_set){
318 | $logic = $rule_set->get_logic();
319 | $rules = $rule_set->get_condition_rules();
320 |
321 | $new_condition_rule_set_obj = new WEPO_Condition_Rule_Set();
322 | $new_condition_rule_set_obj->set_logic($logic);
323 |
324 | $cr_set = array();
325 |
326 | if($rules && is_array($rules)){
327 | foreach($rules as $condition_rule){
328 | $rule_logic = $condition_rule->get_logic();
329 | $condition_sets = $condition_rule->get_condition_sets();
330 |
331 | $new_condition_rule_obj = new WEPO_Condition_Rule();
332 | $new_condition_rule_obj->set_logic($rule_logic);
333 |
334 | $c_rule = array();
335 |
336 | if($condition_sets && is_array($condition_sets)){
337 | foreach($condition_sets as $condition_set){
338 | $cs_logic = $condition_set->get_logic();
339 | $conditions = $condition_set->get_conditions();
340 |
341 | $new_condition_set_obj = new WEPO_Condition_Set();
342 | $new_condition_set_obj->set_logic($cs_logic);
343 |
344 | $c_set = array();
345 |
346 | if($conditions && is_array($conditions)){
347 | foreach($conditions as $condition){
348 | $subject = $condition->get_subject();
349 | $comparison = $condition->get_comparison();
350 | $value = $condition->get_value();
351 |
352 | $new_condition_obj = new WEPO_Condition();
353 | $new_condition_obj->set_operand_type($subject);
354 | $new_condition_obj->set_operand($value);
355 | $new_condition_obj->set_operator($comparison);
356 | $new_condition_obj->set_value('');
357 |
358 | $new_condition_set_obj->add_condition($new_condition_obj);
359 |
360 | $c = array();
361 | $c['operand_type'] = $subject;
362 | $c['operand'] = $value;
363 | $c['operator'] = $comparison;
364 | $c['value'] = '';
365 |
366 | array_push($c_set, $c);
367 | }
368 | }
369 | $new_condition_rule_obj->add_condition_set($new_condition_set_obj);
370 | array_push($c_rule, $c_set);
371 | }
372 | }
373 | $new_condition_rule_set_obj->add_condition_rule($new_condition_rule_obj);
374 | array_push($cr_set, $c_rule);
375 | }
376 | }
377 | $new_condition_rule_sets[] = $new_condition_rule_set_obj;
378 | array_push($cr_sets, $cr_set);
379 | }
380 | }
381 | }
382 |
383 | $new_conditional_rules_json = json_encode($cr_sets);
384 | $new_conditional_rules_json = rawurlencode($new_conditional_rules_json);
385 | $new_conditional_rules_json = trim(stripslashes($new_conditional_rules_json));
386 |
387 | $object->set_property('rules_action', 'show');
388 | $object->set_property('conditional_rules', $new_condition_rule_sets);
389 | $object->set_property('conditional_rules_json', $new_conditional_rules_json);
390 |
391 | return $object;
392 | }
393 |
394 | public static function may_copy_advanced_settings(){
395 | $settings = THWEPO_Utils::get_advanced_settings();
396 |
397 | if(!($settings && is_array($settings))){
398 | $settings = array();
399 | $fsettings = get_option('thwepof_advanced_settings');
400 |
401 | if($fsettings && is_array($fsettings)){
402 | $settings_mapping = array(
403 | 'add_to_cart_text_addon' => 'add_to_cart_text_addon',
404 | 'add_to_cart_text_simple' => 'add_to_cart_text_simple',
405 | 'add_to_cart_text_variable' => 'add_to_cart_text_variable',
406 | 'hide_in_cart' => 'hide_in_cart',
407 | 'hide_in_checkout' => 'hide_in_checkout',
408 | 'hide_in_order' => 'hide_in_order',
409 | );
410 |
411 | foreach ($settings_mapping as $fkey => $pkey) {
412 | if(isset($fsettings[$fkey])){
413 | $settings[$pkey] = $fsettings[$fkey];
414 | }
415 | }
416 |
417 | if(!empty($settings)){
418 | $result = update_option(THWEPO_Utils::OPTION_KEY_ADVANCED_SETTINGS, $settings);
419 | }
420 | }
421 | }
422 | }
423 | }
424 |
425 | endif;
--------------------------------------------------------------------------------
/includes/class-thwepo-autoloader.php:
--------------------------------------------------------------------------------
1 | 'includes/model/rules/class-wepo-condition.php',
24 | 'wepo_condition_set' => 'includes/model/rules/class-wepo-condition-set.php',
25 | 'wepo_condition_rule' => 'includes/model/rules/class-wepo-rule.php',
26 | 'wepo_condition_rule_set' => 'includes/model/rules/class-wepo-rule-set.php',
27 |
28 | 'wepo_product_page_section' => 'includes/model/class-wepo-section.php',
29 | 'wepo_product_field' => 'includes/model/fields/class-wepo-field.php',
30 | 'wepo_product_field_inputtext' => 'includes/model/fields/class-wepo-field-inputtext.php',
31 | 'wepo_product_field_hidden' => 'includes/model/fields/class-wepo-field-hidden.php',
32 | 'wepo_product_field_password' => 'includes/model/fields/class-wepo-field-password.php',
33 | 'wepo_product_field_number' => 'includes/model/fields/class-wepo-field-number.php',
34 | 'wepo_product_field_tel' => 'includes/model/fields/class-wepo-field-tel.php',
35 | 'wepo_product_field_textarea' => 'includes/model/fields/class-wepo-field-textarea.php',
36 | 'wepo_product_field_select' => 'includes/model/fields/class-wepo-field-select.php',
37 | 'wepo_product_field_multiselect' => 'includes/model/fields/class-wepo-field-multiselect.php',
38 | 'wepo_product_field_radio' => 'includes/model/fields/class-wepo-field-radio.php',
39 | 'wepo_product_field_checkbox' => 'includes/model/fields/class-wepo-field-checkbox.php',
40 | 'wepo_product_field_checkboxgroup' => 'includes/model/fields/class-wepo-field-checkboxgroup.php',
41 | 'wepo_product_field_datepicker' => 'includes/model/fields/class-wepo-field-datepicker.php',
42 | 'wepo_product_field_timepicker' => 'includes/model/fields/class-wepo-field-timepicker.php',
43 | 'wepo_product_field_file' => 'includes/model/fields/class-wepo-field-file.php',
44 | 'wepo_product_field_heading' => 'includes/model/fields/class-wepo-field-heading.php',
45 | 'wepo_product_field_html' => 'includes/model/fields/class-wepo-field-html.php',
46 | 'wepo_product_field_label' => 'includes/model/fields/class-wepo-field-label.php',
47 | 'wepo_product_field_colorpicker' => 'includes/model/fields/class-wepo-field-colorpicker.php',
48 |
49 | 'wepo_wpml_currency_switcher_handler' => 'includes/compatibility/class-wepo-wpml-currency-switcher-handler.php',
50 | );
51 |
52 | public function __construct() {
53 | $this->include_path = untrailingslashit(THWEPO_PATH);
54 |
55 | if(function_exists("__autoload")){
56 | spl_autoload_register("__autoload");
57 | }
58 | spl_autoload_register(array($this, 'autoload'));
59 | }
60 |
61 | /** Include a class file. */
62 | private function load_file( $path ) {
63 | if ( $path && is_readable( $path ) ) {
64 | require_once( $path );
65 | return true;
66 | }
67 | return false;
68 | }
69 |
70 | public function autoload_( $class ) {
71 | if(isset($this->class_path[$class])){
72 | $file = $this->class_path[$class];
73 | $this->load_file( TH_WEPO_PATH.$file );
74 | }
75 | }
76 |
77 | /** Class name to file name. */
78 | private function get_file_name_from_class( $class ) {
79 | return 'class-' . str_replace( '_', '-', $class ) . '.php';
80 | }
81 |
82 | public function autoload( $class ) {
83 | $class = strtolower( $class );
84 | $file = $this->get_file_name_from_class( $class );
85 | $path = '';
86 | $file_path = '';
87 | if (isset($this->class_path[$class])){
88 | $file_path = $this->include_path . '/' . $this->class_path[$class];
89 | } else {
90 | if (strpos($class, 'thwepo_admin') === 0){
91 | $path = $this->include_path . '/admin/';
92 | } elseif (strpos($class, 'thwepo_public') === 0){
93 | $path = $this->include_path . '/public/';
94 | } elseif (strpos($class, 'thwepo_utils') === 0){
95 | $path = $this->include_path . '/includes/utils/';
96 | } else{
97 | $path = $this->include_path . '/includes/';
98 | }
99 | $file_path = $path . $file;
100 | }
101 |
102 | if( empty($file_path) || (!$this->load_file($file_path) && strpos($class, 'thwepo_') === 0) ) {
103 | $this->load_file( $this->include_path . $file );
104 | }
105 | }
106 | }
107 |
108 | endif;
109 |
110 | new THWEPO_Autoloader();
111 |
--------------------------------------------------------------------------------
/includes/class-thwepo-data.php:
--------------------------------------------------------------------------------
1 | $value_arr,
43 | 'orderby' => 'name',
44 | 'order' => 'ASC',
45 | 'return' => 'ids',
46 | 'limit' => $limit,
47 | );
48 | $products = $this->get_products($args);
49 |
50 | if(is_array($products) && !empty($products)){
51 | foreach($products as $pid){
52 | $productsList[] = array("id" => $pid, "text" => get_the_title($pid), "selected" => true);
53 | }
54 | }
55 |
56 | $count = count($products);
57 |
58 | }else{
59 | $term = isset($_POST['term']) ? stripslashes($_POST['term']) : '';
60 | $page = isset($_POST['page']) ? stripslashes($_POST['page']) : 1;
61 |
62 | $status = apply_filters('thwepo_load_products_status', 'publish');
63 |
64 | $args = array(
65 | 's' => $term,
66 | 'limit' => $limit,
67 | 'page' => $page,
68 | 'status' => $status,
69 | 'orderby' => 'name',
70 | 'order' => 'ASC',
71 | 'return' => 'ids'
72 | );
73 | $products = $this->get_products($args);
74 |
75 | if(is_array($products) && !empty($products)){
76 | foreach($products as $pid){
77 | $productsList[] = array("id" => $pid, "text" => get_the_title($pid));
78 | //$productsList[] = array("id" => $product->ID, "title" => $product->post_title);
79 | }
80 | }
81 |
82 | $count = count($products);
83 | }
84 |
85 | $morePages = $count < $limit ? false : true;
86 |
87 | $results = array(
88 | "results" => $productsList,
89 | "pagination" => array( "more" => $morePages )
90 | );
91 |
92 | wp_send_json_success($results);
93 | die();
94 | }
95 |
96 | public function get_products($args){
97 | $products = false;
98 | $is_wpml_active = THWEPO_Utils::is_wpml_active();
99 |
100 | if($is_wpml_active){
101 | global $sitepress;
102 | global $icl_adjust_id_url_filter_off;
103 |
104 | $orig_flag_value = $icl_adjust_id_url_filter_off;
105 | $icl_adjust_id_url_filter_off = true;
106 | $default_lang = $sitepress->get_default_language();
107 | $current_lang = $sitepress->get_current_language();
108 | $sitepress->switch_lang($default_lang);
109 |
110 | $products = wc_get_products($args);
111 |
112 | $sitepress->switch_lang($current_lang);
113 | $icl_adjust_id_url_filter_off = $orig_flag_value;
114 | }else{
115 | $products = wc_get_products($args);
116 | }
117 | return $products;
118 | }
119 |
120 | /*public function get_products($only_id = false){
121 | $skip = $this->skip_products_loading();
122 |
123 | if(!$skip){
124 | if(empty($this->products)){
125 | $this->products = $this->load_products($only_id);
126 | }
127 | }
128 | return $this->products;
129 | }*/
130 |
131 | /*private function load_products($only_id = false){
132 | $productsList = array();
133 |
134 | $limit = apply_filters('thwepo_load_products_per_page', -1);
135 | $status = apply_filters('thwepo_load_products_status', 'publish');
136 | $only_id = apply_filters('thwepo_load_products_id_only', $only_id);
137 |
138 | $args = array(
139 | 'status' => $status,
140 | 'limit' => $limit,
141 | 'orderby' => 'name',
142 | 'order' => 'ASC',
143 | 'return' => 'ids'
144 | );
145 | $products = wc_get_products( $args );
146 |
147 | if(!empty($products)){
148 | if($only_id){
149 | return $products;
150 | }else{
151 | foreach($products as $pid){
152 | //$productsList[] = array("id" => $product->ID, "title" => $product->post_title);
153 | $productsList[] = array("id" => $pid, "title" => get_the_title($pid));
154 | }
155 | }
156 | }
157 | return $productsList;
158 | }*/
159 |
160 | /*private function skip_products_loading(){
161 | $skip = apply_filters('thwepo_disable_product_dropdown', false);
162 | return $skip;
163 | }*/
164 | }
165 |
166 | endif;
--------------------------------------------------------------------------------
/includes/class-thwepo-deactivator.php:
--------------------------------------------------------------------------------
1 | get_property('minfile');
42 | $max_count = $field->get_property('maxfile');
43 | $passed = true;
44 | $title = $field->get_property('title');
45 | if( empty( $min_count ) && empty( $max_count ) ){
46 | return true;
47 | }
48 |
49 | if( ( $min_count === $max_count ) && ($min_count !== $file_count ) ){
50 | THWEPO_Utils::add_error(''.$title.': '. sprintf(THWEPO_i18n::__t('%d files need to be uploaded.'), $min_count ) );
51 | $passed = false;
52 |
53 | }else if( $file_count < $min_count ){
54 | THWEPO_Utils::add_error(''.$title.': '. sprintf(THWEPO_i18n::__t('Minimum of %d files need to be uploaded.'), $min_count ) );
55 | $passed = false;
56 |
57 | }else if( $file_count > $max_count ){
58 | THWEPO_Utils::add_error(''.$title.': '. sprintf(THWEPO_i18n::__t('Maximum of %d files need to be uploaded.'), $max_count ) );
59 | $passed = false;
60 | }
61 | return $passed;
62 | }
63 |
64 | public function validate_file($passed, $field, $file){
65 | if($field->get_property('required') && !$file) {
66 | THWEPO_Utils::add_error( sprintf(THWEPO_i18n::__t('Please select a file for %s'), $field->get_property('title')) );
67 | $passed = false;
68 | }
69 | $title = THWEPO_Utils_Field::get_display_label($field);
70 |
71 | if($file){
72 | $file_type = THWEPO_Utils::get_posted_file_type($file);
73 | $file_size = isset($file['size']) ? $file['size'] : false;
74 |
75 | if($file_type && $file_size){
76 | $name = $field->get_property('name');
77 | $maxsize = apply_filters('thwepo_file_upload_maxsize', $field->get_property('maxsize'), $name);
78 | $maxsize_bytes = is_numeric($maxsize) ? $maxsize*1048576 : false;
79 | $accept = apply_filters('thwepo_file_upload_accepted_file_types', $field->get_property('accept'), $name);
80 | $accept = $accept && !is_array($accept) ? array_map('trim', explode(",", $accept)) : $accept;
81 |
82 | if(is_array($accept) && !empty($accept) && !in_array($file_type, $accept)){
83 | THWEPO_Utils::add_error(''.$title.' '. sprintf(THWEPO_i18n::__t('Invalid file type.')));
84 | $passed = false;
85 |
86 | }else if($maxsize_bytes && is_numeric($maxsize_bytes) && $file_size >= $maxsize_bytes){
87 | THWEPO_Utils::add_error(''.$title.' '. sprintf(THWEPO_i18n::__t('File too large. File must be less than %s megabytes.'), $maxsize));
88 | $passed = false;
89 | }
90 | }else if($field->get_property('required')) {
91 | THWEPO_Utils::add_error(''.$title.' '. sprintf(THWEPO_i18n::__t('Please choose a file to upload')) );
92 | $passed = false;
93 | }
94 | }else if($field->get_property('required')) {
95 | THWEPO_Utils::add_error(''.$title.' '. sprintf(THWEPO_i18n::__t('Please choose a file to upload')) );
96 | $passed = false;
97 | }
98 |
99 | return $passed;
100 | }
101 |
102 | public function prepare_file_upload( $file, $name, $field ){
103 | $posted_value = false;
104 |
105 | if(!$field->get_property('required') && !THWEPO_Utils::is_valid_file($file)){
106 | return false;
107 | }
108 |
109 | $uploaded = $this->upload_file($file, $name, $field);
110 |
111 | if($uploaded && !isset($uploaded['error'])){
112 | $upload_info = array();
113 | $upload_info['name'] = $file['name'];
114 | $upload_info['url'] = $uploaded['url'];
115 |
116 | $posted_value = $upload_info;
117 | //$posted_value = $uploaded['url'] . '/' . $file['name'];
118 | }else{
119 | $title = THWEPO_i18n::__t($field->get_property('title'));
120 | THWEPO_Utils::add_error(''.$title.': '. $uploaded['error']);
121 | return false;
122 | }
123 | return $posted_value;
124 | }
125 |
126 | public function upload_file($file, $name, $field){
127 | $upload = false;
128 |
129 | if(is_array($file)){
130 | if(!function_exists('wp_handle_upload')){
131 | require_once(ABSPATH. 'wp-admin/includes/file.php');
132 | require_once(ABSPATH. 'wp-admin/includes/media.php');
133 | }
134 |
135 | add_filter('upload_dir', array('THWEPO_Utils', 'upload_dir'));
136 | //add_filter('upload_mimes', array('THWEPO_Utils', 'upload_mimes'));
137 | $upload = wp_handle_upload($file, array('test_form' => false));
138 | remove_filter('upload_dir', array('THWEPO_Utils', 'upload_dir'));
139 | //remove_filter('upload_mimes', array('THWEPO_Utils', 'upload_mimes'));
140 |
141 | /*if($upload && !isset($upload['error'])){
142 | echo "File is valid, and was successfully uploaded.\n";
143 | } else {
144 | echo $upload['error'];
145 | }*/
146 | }
147 | return $upload;
148 | }
149 | }
150 |
151 | endif;
--------------------------------------------------------------------------------
/includes/class-thwepo-i18n.php:
--------------------------------------------------------------------------------
1 | actions = array();
42 | $this->filters = array();
43 | }
44 |
45 | /**
46 | * Add a new action to the collection to be registered with WordPress.
47 | *
48 | * @since 2.3.0
49 | * @param string $hook The name of the WordPress action that is being registered.
50 | * @param object $component A reference to the instance of the object on which the action is defined.
51 | * @param string $callback The name of the function definition on the $component.
52 | * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
53 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
54 | */
55 | public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
56 | $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
57 | }
58 |
59 | /**
60 | * Add a new filter to the collection to be registered with WordPress.
61 | *
62 | * @since 2.3.0
63 | * @param string $hook The name of the WordPress filter that is being registered.
64 | * @param object $component A reference to the instance of the object on which the filter is defined.
65 | * @param string $callback The name of the function definition on the $component.
66 | * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
67 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
68 | */
69 | public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
70 | $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
71 | }
72 |
73 | /**
74 | * A utility function that is used to register the actions and hooks into a single
75 | * collection.
76 | *
77 | * @since 2.3.0
78 | * @access private
79 | * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
80 | * @param string $hook The name of the WordPress filter that is being registered.
81 | * @param object $component A reference to the instance of the object on which the filter is defined.
82 | * @param string $callback The name of the function definition on the $component.
83 | * @param int $priority The priority at which the function should be fired.
84 | * @param int $accepted_args The number of arguments that should be passed to the $callback.
85 | * @return array The collection of actions and filters registered with WordPress.
86 | */
87 | private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
88 | $hooks[] = array(
89 | 'hook' => $hook,
90 | 'component' => $component,
91 | 'callback' => $callback,
92 | 'priority' => $priority,
93 | 'accepted_args' => $accepted_args
94 | );
95 |
96 | return $hooks;
97 | }
98 |
99 | /**
100 | * Register the filters and actions with WordPress.
101 | *
102 | * @since 2.3.0
103 | */
104 | public function run() {
105 | foreach ( $this->filters as $hook ) {
106 | add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
107 | }
108 |
109 | foreach ( $this->actions as $hook ) {
110 | add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
111 | }
112 | }
113 | }
114 |
115 | endif;
--------------------------------------------------------------------------------
/includes/class-thwepo.php:
--------------------------------------------------------------------------------
1 | version = THWEPO_VERSION;
56 | } else {
57 | $this->version = '1.0.0';
58 | }
59 | $this->plugin_name = 'woocommerce-extra-product-options-pro';
60 |
61 | $this->load_dependencies();
62 | $this->set_locale();
63 | $this->define_admin_hooks();
64 | $this->define_public_hooks();
65 |
66 | $this->loader->add_action( 'init', $this, 'init' );
67 |
68 | $this->set_compatibility();
69 | }
70 |
71 | public function init(){
72 | $this->define_constants();
73 | //$this->init_auto_updater();
74 | }
75 |
76 | private function define_constants(){
77 | !defined('THWEPO_ASSETS_URL_ADMIN') && define('THWEPO_ASSETS_URL_ADMIN', THWEPO_URL . 'admin/assets/');
78 | !defined('THWEPO_ASSETS_URL_PUBLIC') && define('THWEPO_ASSETS_URL_PUBLIC', THWEPO_URL . 'public/assets/');
79 | !defined('THWEPO_WOO_ASSETS_URL') && define('THWEPO_WOO_ASSETS_URL', WC()->plugin_url() . '/assets/');
80 | }
81 |
82 | /**
83 | * Load the required dependencies for this plugin.
84 | *
85 | * Include the following files that make up the plugin:
86 | *
87 | * - THWEPO_Loader. Orchestrates the hooks of the plugin.
88 | * - THWEPO_i18n. Defines internationalization functionality.
89 | * - THWEPO_Admin. Defines all hooks for the admin area.
90 | * - THWEPO_Public. Defines all hooks for the public side of the site.
91 | *
92 | * Create an instance of the loader which will be used to register the hooks
93 | * with WordPress.
94 | *
95 | * @since 2.3.0
96 | * @access private
97 | */
98 | private function load_dependencies() {
99 | if(!function_exists('is_plugin_active')){
100 | include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
101 | }
102 |
103 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-thwepo-autoloader.php';
104 |
105 | /**
106 | * The class responsible for orchestrating the actions and filters of the
107 | * core plugin.
108 | */
109 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-thwepo-loader.php';
110 |
111 | /**
112 | * The class responsible for defining internationalization functionality
113 | * of the plugin.
114 | */
115 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-thwepo-i18n.php';
116 |
117 | /**
118 | * The class responsible for defining all actions that occur in the admin area.
119 | */
120 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-thwepo-admin.php';
121 |
122 | /**
123 | * The class responsible for defining all actions that occur in the public-facing
124 | * side of the site.
125 | */
126 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-thwepo-public.php';
127 |
128 | $this->loader = new THWEPO_Loader();
129 | }
130 |
131 | /**
132 | * Define the locale for this plugin for internationalization.
133 | *
134 | * Uses the THWEPO_i18n class in order to set the domain and to register the hook
135 | * with WordPress.
136 | *
137 | * @since 2.3.0
138 | * @access private
139 | */
140 | private function set_locale() {
141 | $plugin_i18n = new THWEPO_i18n($this->get_plugin_name());
142 | $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
143 | }
144 |
145 | private function init_auto_updater(){
146 | if(!class_exists('THWEPO_Auto_Update_License') ) {
147 | $api_url = 'https://themehigh.com/';
148 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'class-thwepo-auto-update-license.php';
149 | THWEPO_Auto_Update_License::instance(__FILE__, THWEPO_SOFTWARE_TITLE, THWEPO_VERSION, 'plugin', $api_url, THWEPO_i18n::TEXT_DOMAIN);
150 | }
151 | }
152 |
153 | /**
154 | * Register all of the hooks related to the admin area functionality
155 | * of the plugin.
156 | *
157 | * @since 2.3.0
158 | * @access private
159 | */
160 | private function define_admin_hooks() {
161 | $plugin_admin = new THWEPO_Admin( $this->get_plugin_name(), $this->get_version() );
162 |
163 | $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles_and_scripts' );
164 | $this->loader->add_action( 'admin_menu', $plugin_admin, 'admin_menu' );
165 | $this->loader->add_filter( 'woocommerce_screen_ids', $plugin_admin, 'add_screen_id' );
166 | $this->loader->add_filter( 'plugin_action_links_'.THWEPO_BASE_NAME, $plugin_admin, 'plugin_action_links' );
167 | $this->loader->add_filter( 'plugin_row_meta', $plugin_admin, 'plugin_row_meta', 10, 2 );
168 |
169 | $wepo_data = THWEPO_Data::instance();
170 |
171 | $this->loader->add_action('wp_ajax_thwepo_load_products', $wepo_data, 'load_products_ajax');
172 | $this->loader->add_action('wp_ajax_nopriv_thwepo_load_products', $wepo_data, 'load_products_ajax');
173 | }
174 |
175 | /**
176 | * Register all of the hooks related to the public-facing functionality
177 | * of the plugin.
178 | *
179 | * @since 2.3.0
180 | * @access private
181 | */
182 | private function define_public_hooks() {
183 | $plugin_public = new THWEPO_Public( $this->get_plugin_name(), $this->get_version() );
184 |
185 | $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles_and_scripts', 20 );
186 | }
187 |
188 | /**
189 | * Include files to provide compatibility with requested plugins
190 | *
191 | *
192 | * @since 2.3.0
193 | * @access private
194 | *
195 | * @return null
196 | */
197 | private function set_compatibility(){
198 | if( apply_filters( 'thwepo_wpml_currency_swithcer_compatibility', false ) ){
199 | new WEPO_WPML_Currency_Switcher_Handler();
200 | }
201 | }
202 |
203 | /**
204 | * Run the loader to execute all of the hooks with WordPress.
205 | *
206 | * @since 2.3.0
207 | */
208 | public function run() {
209 | $this->loader->run();
210 | }
211 |
212 | /**
213 | * The name of the plugin used to uniquely identify it within the context of
214 | * WordPress and to define internationalization functionality.
215 | *
216 | * @since 2.3.0
217 | * @return string The name of the plugin.
218 | */
219 | public function get_plugin_name() {
220 | return $this->plugin_name;
221 | }
222 |
223 | /**
224 | * The reference to the class that orchestrates the hooks with the plugin.
225 | *
226 | * @since 2.3.0
227 | * @return THWEPO_Loader Orchestrates the hooks of the plugin.
228 | */
229 | public function get_loader() {
230 | return $this->loader;
231 | }
232 |
233 | /**
234 | * Retrieve the version number of the plugin.
235 | *
236 | * @since 2.3.0
237 | * @return string The version number of the plugin.
238 | */
239 | public function get_version() {
240 | return $this->version;
241 | }
242 | }
243 |
244 | endif;
--------------------------------------------------------------------------------
/includes/compatibility/class-wepo-wpml-currency-switcher-handler.php:
--------------------------------------------------------------------------------
1 |
2 | cart_contents as $key => &$value) {
30 | $extra_options = isset($value['thwepo_options']) ? $value['thwepo_options'] : false;
31 | if($extra_options) {
32 | global $woocommerce;
33 | $is_currency_switched = $woocommerce->session->get( 'client_currency_switched');
34 | $wepo_currency_flag = $woocommerce->session->get( 'wepo_client_currency_switched');
35 | if($is_currency_switched && $wepo_currency_flag){
36 | $value['thwepo-original_price'] = $value['data']->get_price('');
37 | $woocommerce->session->set( 'wepo_client_currency_switched', false );
38 | }
39 | }
40 | }
41 |
42 | }
43 |
44 | public function wpml_currency_val($price, $name, $price_info, $product_info){
45 | if($price){
46 | $price = $this->convert_price_as_per_currency_used($price);
47 | }
48 |
49 | return $price;
50 | }
51 |
52 | public function wpml_currency_swictched(){
53 | global $woocommerce;
54 | $woocommerce->session->set( 'wepo_client_currency_switched', true );
55 | }
56 |
57 | public function add_action_to_multi_currency_ajax( $array ) {
58 | $array[] = 'thwepo_calculate_extra_cost'; // Add a AJAX action to the array
59 | return $array;
60 | }
61 |
62 | public function change_display_price_as_per_currency($price, $product_price, $price_type){
63 | if($price){
64 | $price = $this->convert_price_as_per_currency_used($price);
65 | }
66 |
67 | return $price;
68 | }
69 |
70 | public function change_option_price($price, $price_type, $option, $name){
71 | if($price){
72 | $price = $this->convert_price_as_per_currency_used($price);
73 | }
74 |
75 | return $price;
76 | }
77 |
78 | public function is_woocommmerce_wpml_actice(){
79 | $is_currency_switcher_active = is_plugin_active('woocommerce-multilingual/wpml-woocommerce.php');
80 | return $is_currency_switcher_active;
81 | }
82 |
83 | public function convert_price_as_per_currency_used($price){
84 | global $woocommerce, $woocommerce_wpml;
85 | $is_active = is_woocommmerce_wpml_actice();
86 |
87 | if($price && $is_active){
88 | $multi_currency = $woocommerce_wpml->get_multi_currency();
89 | if($multi_currency){
90 | $currency_settings = $woocommerce_wpml->get_setting( 'currency_options' );
91 | $currecy_switcher = new WCML_Multi_Currency_Prices($multi_currency, $currency_settings);
92 |
93 | if($currecy_switcher){
94 | $price = $currecy_switcher->raw_price_filter($price);
95 | }
96 | }
97 | }
98 |
99 | return $price;
100 | }
101 | }
102 |
103 | endif;
--------------------------------------------------------------------------------
/includes/index.php:
--------------------------------------------------------------------------------
1 | $name = $value;
62 | }
63 | }
64 |
65 | public function get_property($name){
66 | if(property_exists($this, $name)){
67 | return $this->$name;
68 | }else{
69 | return '';
70 | }
71 | }
72 | }
73 |
74 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-checkbox.php:
--------------------------------------------------------------------------------
1 | type = 'checkbox';
20 | }
21 | }
22 |
23 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-checkboxgroup.php:
--------------------------------------------------------------------------------
1 | type = 'checkboxgroup';
20 | }
21 | }
22 |
23 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-colorpicker.php:
--------------------------------------------------------------------------------
1 | type = 'colorpicker';
23 | }
24 | }
25 |
26 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-datepicker.php:
--------------------------------------------------------------------------------
1 | type = 'datepicker';
39 | }
40 | }
41 |
42 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-factory.php:
--------------------------------------------------------------------------------
1 | type = 'file';
24 | }
25 | }
26 |
27 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-heading.php:
--------------------------------------------------------------------------------
1 | type = 'heading';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-hidden.php:
--------------------------------------------------------------------------------
1 | type = 'hidden';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-html.php:
--------------------------------------------------------------------------------
1 | type = 'html';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-inputtext.php:
--------------------------------------------------------------------------------
1 | type = 'inputtext';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-label.php:
--------------------------------------------------------------------------------
1 | type = 'label';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-multiselect.php:
--------------------------------------------------------------------------------
1 | type = 'multiselect';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-number.php:
--------------------------------------------------------------------------------
1 | type = 'number';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-password.php:
--------------------------------------------------------------------------------
1 | type = 'password';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-radio.php:
--------------------------------------------------------------------------------
1 | type = 'radio';
20 | }
21 | }
22 |
23 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-select.php:
--------------------------------------------------------------------------------
1 | type = 'select';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-tel.php:
--------------------------------------------------------------------------------
1 | type = 'tel';
18 | }
19 | }
20 |
21 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-textarea.php:
--------------------------------------------------------------------------------
1 | type = 'textarea';
21 | }
22 | }
23 |
24 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field-timepicker.php:
--------------------------------------------------------------------------------
1 | type = 'timepicker';
23 | }
24 | }
25 |
26 | endif;
--------------------------------------------------------------------------------
/includes/model/fields/class-wepo-field.php:
--------------------------------------------------------------------------------
1 | $name = $value;
94 | }
95 |
96 | public function get_property($name){
97 | $value = '';
98 |
99 | if(property_exists($this, $name)){
100 | $value = $this->$name;
101 | }
102 |
103 | return apply_filters( 'thwepo_field_property_value', $value, $name, $this );
104 | }
105 | }
106 |
107 | endif;
--------------------------------------------------------------------------------
/includes/model/rules/class-wepo-condition-set.php:
--------------------------------------------------------------------------------
1 | get_conditions();
29 | if(!empty($conditions)){
30 | if($this->get_logic() === self::LOGIC_AND){
31 | foreach($conditions as $condition){
32 | if(!$condition->is_satisfied($product, $categories, $tags)){
33 | $satisfied = false;
34 | break;
35 | }
36 | }
37 | }else if($this->get_logic() === self::LOGIC_OR){
38 | $satisfied = false;
39 | foreach($conditions as $condition){
40 | if($condition->is_satisfied($product, $categories, $tags)){
41 | $satisfied = true;
42 | break;
43 | }
44 | }
45 | }
46 | }
47 | return $satisfied;
48 | }
49 |
50 | public function add_condition($condition){
51 | if(isset($condition) && $condition instanceof WEPO_Condition && $condition->is_valid()){
52 | $this->conditions[] = $condition;
53 | }
54 | }
55 |
56 | public function set_logic($logic){
57 | $this->logic = $logic;
58 | }
59 | public function get_logic(){
60 | return $this->logic;
61 | }
62 |
63 | public function set_conditions($conditions){
64 | $this->conditions = $conditions;
65 | }
66 | public function get_conditions(){
67 | return $this->conditions;
68 | }
69 | }
70 |
71 | endif;
--------------------------------------------------------------------------------
/includes/model/rules/class-wepo-condition.php:
--------------------------------------------------------------------------------
1 | operand_type) && !empty($this->operator)){
43 | return true;
44 | }
45 | return false;
46 | }
47 |
48 | public function is_satisfied($product, $categories, $tags=false){
49 | $satisfied = true;
50 | if($this->is_valid()){
51 | $operands = $this->operand;
52 |
53 | if(!empty($operands) && !in_array(-1, $operands)){
54 | if($this->operand_type == self::PRODUCT){
55 | if($this->operator == self::EQUALS) {
56 | if(!in_array($product, $operands)){
57 | return false;
58 | }
59 | }else if($this->operator == self::NOT_EQUALS){
60 | if(in_array($product, $operands)){
61 | return false;
62 | }
63 | }
64 | }else if($this->operand_type == self::CATEGORY){
65 | $commonCategories = array_intersect($categories, $operands);
66 |
67 | if($this->operator == self::EQUALS) {
68 | if(empty($commonCategories)){
69 | return false;
70 | }
71 | }else if($this->operator == self::NOT_EQUALS){
72 | if(!empty($commonCategories)){
73 | return false;
74 | }
75 | }
76 | }else if($this->subject == self::TAG){
77 | $commonTags = array_intersect($tags, $operands);
78 |
79 | if($this->operator == self::EQUALS) {
80 | if(empty($commonTags)){
81 | return false;
82 | }
83 | }else if($this->operator == self::NOT_EQUALS){
84 | if(!empty($commonTags)){
85 | return false;
86 | }
87 | }
88 | }
89 | }
90 | }
91 | return $satisfied;
92 | }
93 |
94 | public function set_operand_type($operand_type){
95 | $this->operand_type = $operand_type;
96 | }
97 | public function get_operand_type(){
98 | return $this->operand_type;
99 | }
100 |
101 | public function set_operand($operand){
102 | $this->operand = $operand;
103 | }
104 | public function get_operand(){
105 | return $this->operand;
106 | }
107 |
108 | public function set_operator($operator){
109 | $this->operator = $operator;
110 | }
111 | public function get_operator(){
112 | return $this->operator;
113 | }
114 |
115 | public function set_value($value){
116 | $this->value = $value;
117 | }
118 | public function get_value(){
119 | return $this->value;
120 | }
121 | }
122 |
123 | endif;
--------------------------------------------------------------------------------
/includes/model/rules/class-wepo-rule-set.php:
--------------------------------------------------------------------------------
1 | get_condition_rules();
29 | if(!empty($condition_rules)){
30 | if($this->get_logic() === self::LOGIC_AND){
31 | foreach($condition_rules as $condition_rule){
32 | if(!$condition_rule->is_satisfied($product, $categories, $tags)){
33 | $satisfied = false;
34 | break;
35 | }
36 | }
37 | }else if($this->get_logic() === self::LOGIC_OR){
38 | $satisfied = false;
39 | foreach($condition_rules as $condition_rule){
40 | if($condition_rule->is_satisfied($product, $categories, $tags)){
41 | $satisfied = true;
42 | break;
43 | }
44 | }
45 | }
46 | }
47 | return $satisfied;
48 | }
49 |
50 | public function add_condition_rule($condition_rule){
51 | if(isset($condition_rule) && $condition_rule instanceof WEPO_Condition_Rule){
52 | $this->condition_rules[] = $condition_rule;
53 | }
54 | }
55 |
56 | public function set_logic($logic){
57 | $this->logic = $logic;
58 | }
59 | public function get_logic(){
60 | return $this->logic;
61 | }
62 |
63 | public function set_condition_rules($condition_rules){
64 | $this->condition_rules = $condition_rules;
65 | }
66 | public function get_condition_rules(){
67 | return $this->condition_rules;
68 | }
69 | }
70 |
71 | endif;
--------------------------------------------------------------------------------
/includes/model/rules/class-wepo-rule.php:
--------------------------------------------------------------------------------
1 | get_condition_sets();
29 | if(!empty($condition_sets)){
30 | if($this->get_logic() === self::LOGIC_AND){
31 | foreach($condition_sets as $condition_set){
32 | if(!$condition_set->is_satisfied($product, $categories, $tags)){
33 | $satisfied = false;
34 | break;
35 | }
36 | }
37 | }else if($this->get_logic() === self::LOGIC_OR){
38 | $satisfied = false;
39 | foreach($condition_sets as $condition_set){
40 | if($condition_set->is_satisfied($product, $categories, $tags)){
41 | $satisfied = true;
42 | break;
43 | }
44 | }
45 | }
46 | }
47 | return $satisfied;
48 | }
49 |
50 | public function add_condition_set($condition_set){
51 | if(isset($condition_set) && $condition_set instanceof WEPO_Condition_Set){
52 | $this->condition_sets[] = $condition_set;
53 | }
54 | }
55 |
56 | public function set_logic($logic){
57 | $this->logic = $logic;
58 | }
59 | public function get_logic(){
60 | return $this->logic;
61 | }
62 |
63 | public function set_condition_sets($condition_sets){
64 | $this->condition_sets = $condition_sets;
65 | }
66 | public function get_condition_sets(){
67 | return $this->condition_sets;
68 | }
69 | }
70 |
71 | endif;
--------------------------------------------------------------------------------
/includes/utils/class-thwepo-utils-condition.php:
--------------------------------------------------------------------------------
1 | operand_type) && !empty($condition->operator)){
33 | return true;
34 | }
35 | return false;
36 | }
37 |
38 | public static function is_satisfied($rules_set_list, $product, $categories, $tags=false){
39 | $valid = true;
40 | if(is_array($rules_set_list) && !empty($rules_set_list)){
41 | foreach($rules_set_list as $rules_set){
42 | if(!self::is_satisfied_rules_set($rules_set, $product, $categories, $tags)){
43 | $valid = false;
44 | }
45 | }
46 | }
47 | return $valid;
48 | }
49 |
50 | private static function is_satisfied_condition($condition, $product, $categories, $tags){
51 | $satisfied = true;
52 | if(self::is_valid_condition($condition)){
53 | $op_type = $condition->operand_type;
54 | $operator = $condition->operator;
55 | $operands = $condition->operand;
56 |
57 | if(!empty($operands) && !in_array(-1, $operands)){
58 | if($op_type == self::OP_TYPE_PRODUCT){
59 | $product = THWEPO_Utils::get_original_product_id($product);
60 |
61 | if($operator == self::OPERATOR_EQUALS) {
62 | if(!in_array($product, $operands)){
63 | return false;
64 | }
65 | }else if($operator == self::OPERATOR_NOT_EQUALS){
66 | if(in_array($product, $operands)){
67 | return false;
68 | }
69 | }
70 | }else if($op_type == self::OP_TYPE_CATEGORY){
71 | $commonCategories = array_intersect($categories, $operands);
72 |
73 | if($operator == self::OPERATOR_EQUALS) {
74 | if(empty($commonCategories)){
75 | return false;
76 | }
77 | }else if($operator == self::OPERATOR_NOT_EQUALS){
78 | if(!empty($commonCategories)){
79 | return false;
80 | }
81 | }
82 | }else if($op_type == self::OP_TYPE_TAG){
83 | $commonTags = array_intersect($tags, $operands);
84 |
85 | if($operator == self::OPERATOR_EQUALS) {
86 | if(empty($commonTags)){
87 | return false;
88 | }
89 | }else if($operator == self::OPERATOR_NOT_EQUALS){
90 | if(!empty($commonTags)){
91 | return false;
92 | }
93 | }
94 | }else if($op_type === self::OP_TYPE_USER){
95 | $user_roles = THWEPO_Utils::get_user_roles();
96 |
97 | if(is_array($user_roles) && is_array($operands)){
98 | $intersection = array_intersect($user_roles, $operands);
99 |
100 | if($operator == self::OPERATOR_EQUALS) {
101 | if(empty($intersection)){
102 | return false;
103 | }
104 | }else if($operator == self::OPERATOR_NOT_EQUALS){
105 | if(!empty($intersection)){
106 | return false;
107 | }
108 | }
109 | }
110 | }
111 | }
112 | }
113 | return $satisfied;
114 | }
115 |
116 | private static function is_satisfied_rules_set($rules_set, $product, $categories, $tags){
117 | $satisfied = true;
118 | $condition_rules = $rules_set->get_condition_rules();
119 | $logic = $rules_set->get_logic();
120 |
121 | if(!empty($condition_rules)){
122 | if($logic === self::LOGIC_AND){
123 | foreach($condition_rules as $condition_rule){
124 | if(!self::is_satisfied_rule($condition_rule, $product, $categories, $tags)){
125 | $satisfied = false;
126 | break;
127 | }
128 | }
129 | }else if($logic === self::LOGIC_OR){
130 | $satisfied = false;
131 | foreach($condition_rules as $condition_rule){
132 | if(self::is_satisfied_rule($condition_rule, $product, $categories, $tags)){
133 | $satisfied = true;
134 | break;
135 | }
136 | }
137 | }
138 | }
139 | return $satisfied;
140 | }
141 |
142 | private static function is_satisfied_rule($rule, $product, $categories, $tags){
143 | $satisfied = true;
144 | $conditions_set_list = $rule->get_condition_sets();
145 | $logic = $rule->get_logic();
146 |
147 | if(!empty($conditions_set_list)){
148 | if($logic === self::LOGIC_AND){
149 | foreach($conditions_set_list as $conditions_set){
150 | if(!self::is_satisfied_conditions_set($conditions_set, $product, $categories, $tags)){
151 | $satisfied = false;
152 | break;
153 | }
154 | }
155 | }else if($logic === self::LOGIC_OR){
156 | $satisfied = false;
157 | foreach($conditions_set_list as $conditions_set){
158 | if(self::is_satisfied_conditions_set($conditions_set, $product, $categories, $tags)){
159 | $satisfied = true;
160 | break;
161 | }
162 | }
163 | }
164 | }
165 | return $satisfied;
166 | }
167 |
168 | private static function is_satisfied_conditions_set($conditions_set, $product, $categories, $tags){
169 | $satisfied = true;
170 | $conditions = $conditions_set->get_conditions();
171 | $logic = $conditions_set->get_logic();
172 |
173 | if(!empty($conditions)){
174 | if($logic === self::LOGIC_AND){
175 | foreach($conditions as $condition){
176 | if(!self::is_satisfied_condition($condition, $product, $categories, $tags)){
177 | $satisfied = false;
178 | break;
179 | }
180 | }
181 | }else if($logic === self::LOGIC_OR){
182 | $satisfied = false;
183 | foreach($conditions as $condition){
184 | if(self::is_satisfied_condition($condition, $product, $categories, $tags)){
185 | $satisfied = true;
186 | break;
187 | }
188 | }
189 | }
190 | }
191 | return $satisfied;
192 | }
193 |
194 | public static function prepare_conditional_rules($posted, $ajax=false){
195 | $iname = $ajax ? 'i_rules_ajax' : 'i_rules';
196 | $conditional_rules = isset($posted[$iname]) ? trim(stripslashes($posted[$iname])) : '';
197 |
198 | $condition_rule_sets = array();
199 | if(!empty($conditional_rules)){
200 | $conditional_rules = urldecode($conditional_rules);
201 | $rule_sets = json_decode($conditional_rules, true);
202 |
203 | if(is_array($rule_sets)){
204 | foreach($rule_sets as $rule_set){
205 | if(is_array($rule_set)){
206 | $condition_rule_set_obj = new WEPO_Condition_Rule_Set();
207 | $condition_rule_set_obj->set_logic('and');
208 |
209 | foreach($rule_set as $condition_sets){
210 | if(is_array($condition_sets)){
211 | $condition_rule_obj = new WEPO_Condition_Rule();
212 | $condition_rule_obj->set_logic('or');
213 |
214 | foreach($condition_sets as $condition_set){
215 | if(is_array($condition_set)){
216 | $condition_set_obj = new WEPO_Condition_Set();
217 | $condition_set_obj->set_logic('and');
218 |
219 | foreach($condition_set as $condition){
220 | if(is_array($condition)){
221 | $condition_obj = new WEPO_Condition();
222 | $condition_obj->set_operand_type(isset($condition['operand_type']) ? $condition['operand_type'] : '');
223 | $condition_obj->set_operand(isset($condition['operand']) ? $condition['operand'] : '');
224 | $condition_obj->set_operator(isset($condition['operator']) ? $condition['operator'] : '');
225 | $condition_obj->set_value(isset($condition['value']) ? trim($condition['value']) : '');
226 |
227 | $condition_set_obj->add_condition($condition_obj);
228 | }
229 | }
230 | $condition_rule_obj->add_condition_set($condition_set_obj);
231 | }
232 | }
233 | $condition_rule_set_obj->add_condition_rule($condition_rule_obj);
234 | }
235 | }
236 | $condition_rule_sets[] = $condition_rule_set_obj;
237 | }
238 | }
239 | }
240 | }
241 | return $condition_rule_sets;
242 | }
243 | }
244 |
245 | endif;
--------------------------------------------------------------------------------
/includes/utils/class-thwepo-utils-core.php:
--------------------------------------------------------------------------------
1 | array('name'=>'name', 'value'=>''),
19 | 'position' => array('name'=>'position', 'value'=>''),
20 | 'order' => array('name'=>'order', 'value'=>''),
21 | 'cssclass' => array('name'=>'cssclass', 'value'=>array(), 'value_type'=>'array'),
22 |
23 | 'title_cell_with' => array('name'=>'title_cell_with', 'value'=>''),
24 | 'field_cell_with' => array('name'=>'field_cell_with', 'value'=>''),
25 |
26 | 'show_title' => array('name'=>'show_title', 'value'=>1, 'value_type'=>'boolean'),
27 | //'custom_section' => array('name'=>'custom_section', 'value'=>1, 'value_type'=>'boolean'),
28 |
29 | 'title' => array('name'=>'title', 'value'=>''),
30 | 'title_type' => array('name'=>'title_type', 'value'=>''),
31 | 'title_color' => array('name'=>'title_color', 'value'=>''),
32 | 'title_position' => array('name'=>'title_position', 'value'=>''),
33 | 'title_class' => array('name'=>'title_class', 'value'=>array(), 'value_type'=>'array'),
34 |
35 | 'subtitle' => array('name'=>'subtitle', 'value'=>''),
36 | 'subtitle_type' => array('name'=>'subtitle_type', 'value'=>''),
37 | 'subtitle_color' => array('name'=>'subtitle_color', 'value'=>''),
38 | 'subtitle_position' => array('name'=>'subtitle_position', 'value'=>''),
39 | 'subtitle_class' => array('name'=>'subtitle_class', 'value'=>array(), 'value_type'=>'array'),
40 | );
41 |
42 | public static function is_valid_section($section){
43 | if(isset($section) && $section instanceof WEPO_Product_Page_Section && !empty($section->name)){
44 | return true;
45 | }
46 | return false;
47 | }
48 |
49 | public static function is_enabled($section){
50 | if($section->get_property('enabled')){
51 | return true;
52 | }
53 | return false;
54 | }
55 |
56 | public static function is_custom_section($section){
57 | //return $section->custom_section;
58 | return true;
59 | }
60 |
61 | public static function has_fields($section){
62 | if($section->get_property('fields')){
63 | return true;
64 | }
65 | return false;
66 | }
67 |
68 | public static function is_show_section($section, $product, $categories, $tags=false){
69 | /*$show = true;
70 | if(!empty($condition_sets)){
71 | foreach($condition_sets as $condition_set){
72 | if($condition_set->show_element()){
73 | $show = false;
74 | }
75 | }
76 | }
77 |
78 | return $show;*/
79 |
80 | $rules_set_list = $section->get_property('conditional_rules');
81 | $valid = THWEPO_Utils_Condition::is_satisfied($rules_set_list, $product, $categories, $tags);
82 |
83 | $show = true;
84 | if($section->get_property('rules_action') === 'hide'){
85 | $show = $valid ? false : true;
86 | }else{
87 | $show = $valid ? true : false;
88 | }
89 | $show = apply_filters('thwepo_show_section', $show, $section->name);
90 | return $show;
91 | }
92 |
93 | public static function prepare_default_section(){
94 | $section = new WEPO_Product_Page_Section();
95 | $section->set_property('id', 'default');
96 | $section->set_property('name', 'default');
97 | $section->set_property('title', 'Default');
98 | $section->set_property('show_title', 0);
99 | $section->set_property('position', 'woo_before_add_to_cart_button');
100 |
101 | return $section;
102 | }
103 |
104 | public static function prepare_section_from_posted_data($posted, $form = 'new'){
105 | $name = isset($posted['i_name']) ? $posted['i_name'] : '';
106 | $position = isset($posted['i_position']) ? $posted['i_position'] : '';
107 | $title = isset($posted['i_title']) ? $posted['i_title'] : '';
108 |
109 | if(!$name || !$title || !$position){
110 | return;
111 | }
112 |
113 | if($form === 'edit'){
114 | $section = THWEPO_Admin_Utils::get_section($name);
115 | }else{
116 | $name = strtolower($name);
117 | $name = is_numeric($name) ? "s_".$name : $name;
118 |
119 | $section = new WEPO_Product_Page_Section();
120 | $section->set_property('id', $name);
121 | }
122 |
123 | foreach( self::$SECTION_PROPS as $pname => $property ){
124 | $iname = 'i_'.$pname;
125 | $pvalue = isset($posted[$iname]) ? trim(stripslashes($posted[$iname])) : $property['value'];
126 |
127 | if($pname === 'show_title'){
128 | $pvalue = !empty($pvalue) && $pvalue === 'yes' ? 1 : 0;
129 | }
130 |
131 | $section->set_property($pname, $pvalue);
132 | }
133 |
134 | $section->set_property('custom_section', 1);
135 |
136 | $section->set_property('rules_action', isset($posted['i_rules_action']) ? trim(stripslashes($posted['i_rules_action'])) : '');
137 | $section->set_property('conditional_rules_json', isset($posted['i_rules']) ? trim(stripslashes($posted['i_rules'])) : '');
138 | $section->set_property('conditional_rules', THWEPO_Utils_Condition::prepare_conditional_rules($posted, false));
139 |
140 | $section->set_property('rules_action_ajax', isset($posted['i_rules_action_ajax']) ? trim(stripslashes($posted['i_rules_action_ajax'])) : '');
141 | $section->set_property('conditional_rules_ajax_json', isset($posted['i_rules_ajax']) ? trim(stripslashes($posted['i_rules_ajax'])) : '');
142 | $section->set_property('conditional_rules_ajax', THWEPO_Utils_Condition::prepare_conditional_rules($posted, true));
143 |
144 | //WPML Support
145 | self::add_wpml_support($section);
146 | return $section;
147 | }
148 |
149 | public static function get_property_set($section){
150 | if(self::is_valid_section($section)){
151 | $props_set = array();
152 |
153 | foreach(self::$SECTION_PROPS as $pname => $props){
154 | $pvalue = $section->get_property($props['name']);
155 |
156 | if(isset($props['value_type']) && $props['value_type'] === 'array' && !empty($pvalue)){
157 | $pvalue = is_array($pvalue) ? $pvalue : explode(',', $pvalue);
158 | }
159 |
160 | if(isset($props['value_type']) && $props['value_type'] != 'boolean'){
161 | $pvalue = empty($pvalue) ? $props['value'] : $pvalue;
162 | }
163 |
164 | $props_set[$pname] = $pvalue;
165 | }
166 |
167 | $props_set['custom'] = self::is_custom_section($section);
168 | $props_set['rules_action'] = $section->get_property('rules_action');
169 | $props_set['rules_action_ajax'] = $section->get_property('rules_action_ajax');
170 |
171 | return $props_set;
172 | }else{
173 | return false;
174 | }
175 | }
176 |
177 | public static function get_property_json($section){
178 | $props_json = '';
179 | $props_set = self::get_property_set($section);
180 |
181 | if($props_set){
182 | $props_json = json_encode($props_set);
183 | }
184 | return $props_json;
185 | }
186 |
187 | public static function add_field($section, $field){
188 | if(self::is_valid_section($section) && THWEPO_Utils_Field::is_valid_field($field)){
189 | $size = sizeof($section->fields);
190 | $field->set_property('order', $size);
191 | $field->set_property('custom_field', 1);
192 | $section->fields[$field->get_property('name')] = $field;
193 | return $section;
194 | }else{
195 | throw new Exception('Invalid Section or Field Object.');
196 | }
197 | }
198 |
199 | public static function update_field($section, $field){
200 | if(self::is_valid_section($section) && THWEPO_Utils_Field::is_valid_field($field)){
201 | $name = $field->get_property('name');
202 | $name_old = $field->get_property('name_old');
203 | $field_set = $section->fields;
204 |
205 | if(!empty($name) && is_array($field_set) && isset($field_set[$name_old])){
206 | $o_field = $field_set[$name_old];
207 | //$index = array_search($name_old, array_keys($field_set));
208 | $field->set_property('order', $o_field->get_property('order'));
209 | $field->set_property('custom_field', $o_field->get_property('custom_field'));
210 | $field_set[$name] = $field;
211 |
212 | if($name != $name_old){
213 | unset($field_set[$name_old]);
214 | }
215 | $field_set = self::sort_field_set($field_set);
216 | $section->set_property('fields', $field_set);
217 | }
218 | return $section;
219 | }else{
220 | throw new Exception('Invalid Section or Field Object.');
221 | }
222 | }
223 |
224 | public static function get_fields($section, $ignore_disabled=false){
225 | $fields = (is_array($section->fields) && !empty($section->fields)) ? $section->fields : array();
226 |
227 | if($ignore_disabled && is_array($fields)){
228 | foreach($fields as $key => $field){
229 | if(!THWEPO_Utils_Field::is_enabled($field)){
230 | unset($fields[$key]);
231 | }
232 | }
233 | }
234 | return $fields;
235 | }
236 |
237 | public static function get_product_sections_and_fields($product){
238 | $product_id = THWEPO_Utils::get_product_id($product);
239 | $categories = THWEPO_Utils::get_product_categories($product_id);
240 | $tags = THWEPO_Utils::get_product_tags($product_id);
241 | $sections = THWEPO_Utils::get_custom_sections();
242 |
243 | if($sections && is_array($sections) && !empty($sections)){
244 | foreach($sections as $section_name => $section){
245 | $section = self::prepare_section_and_fields($section, $product_id, $categories, $tags);
246 | if($section){
247 | $sections[$section_name] = $section;
248 | }else{
249 | unset($sections[$section_name]);
250 | }
251 | }
252 | }
253 | return $sections;
254 | }
255 |
256 | /**
257 | * Check and filter invalid, disabled and conditionally hidden section and fields.
258 | *
259 | * @param $section
260 | * @param $product_id
261 | * @param $categories
262 | * @param $tags
263 | *
264 | * @return $section - A cleaned Section object
265 | */
266 | public static function prepare_section_and_fields($section, $product_id, $categories, $tags=false){
267 | if(self::is_valid_section($section) && self::is_show_section($section, $product_id, $categories, $tags)){
268 | $fields = self::get_fields($section);
269 | if(is_array($fields)){
270 | foreach($fields as $field_name => $field){
271 | if(THWEPO_Utils_Field::is_enabled($field) && THWEPO_Utils_Field::is_show_field($field, $product_id, $categories, $tags)){
272 | $fields[$field_name] = $field;
273 | }else{
274 | unset($fields[$field_name]);
275 | }
276 | }
277 |
278 | if(!empty($fields)){
279 | $section->set_property('fields', $fields);
280 | return $section;
281 | }
282 | }
283 | }
284 | return false;
285 | }
286 |
287 | public static function get_product_fields($product, $names_only = true){
288 | $product_id = THWEPO_Utils::get_product_id($product);
289 | $categories = THWEPO_Utils::get_product_categories($product_id);
290 | $tags = THWEPO_Utils::get_product_tags($product_id);
291 | $sections = THWEPO_Utils::get_custom_sections();
292 | $prod_fields = array();
293 |
294 | if($sections && is_array($sections) && !empty($sections)){
295 | foreach($sections as $section_name => $section){
296 | $fields = self::get_product_section_fields($section, $product_id, $categories, $tags, $names_only);
297 | if($fields){
298 | $prod_fields = array_merge($prod_fields, $fields);
299 | }
300 | }
301 | }
302 | return $prod_fields;
303 | }
304 |
305 | public static function get_product_section_fields($section, $product_id, $categories, $tags=false, $names_only = true){
306 | $prod_fields = array();
307 | if(self::is_valid_section($section) && self::is_show_section($section, $product_id, $categories, $tags)){
308 | $fields = self::get_fields($section);
309 |
310 | if(is_array($fields)){
311 | foreach($fields as $field_name => $field){
312 | if(THWEPO_Utils_Field::is_enabled($field) && THWEPO_Utils_Field::is_show_field($field, $product_id, $categories, $tags)){
313 | if($names_only){
314 | $prod_fields[] = $field_name;
315 | }else{
316 | $prod_fields[$field_name] = $field;
317 | }
318 | }
319 | }
320 | }
321 | }
322 | return $prod_fields;
323 | }
324 |
325 | public static function clear_fields($section){
326 | if(self::is_valid_section($section)){
327 | $section->fields = array();
328 | }
329 | return $section;
330 | }
331 |
332 | public static function sort_fields($section){
333 | uasort($section->fields, array('self', 'sort_by_order'));
334 | return $section;
335 | }
336 |
337 | public static function sort_field_set($field_set){
338 | uasort($field_set, array('self', 'sort_by_order'));
339 | return $field_set;
340 | }
341 |
342 | public static function sort_by_order($a, $b){
343 | if($a->get_property('order') == $b->get_property('order')){
344 | return 0;
345 | }
346 | return ($a->get_property('order') < $b->get_property('order')) ? -1 : 1;
347 | }
348 |
349 | public static function add_wpml_support($section){
350 | THWEPO_i18n::wpml_register_string('Section Title - '.$section->name, $section->title );
351 | THWEPO_i18n::wpml_register_string('Section Subtitle - '.$section->name, $section->subtitle );
352 | }
353 |
354 | /***********************************************
355 | *********** DISPLAY SECTIONS - START **********
356 | ***********************************************/
357 | public static function prepare_section_html($section, $product_type = false){
358 | $field_html = '';
359 | $field_html_hidden = '';
360 | $section_html = '';
361 |
362 | $fields = self::get_fields($section);
363 | if(is_array($fields)){
364 | foreach($fields as $field){
365 | if($field->get_property('type') === 'hidden'){
366 | $field_html_hidden .= THWEPO_Utils_Field::prepare_field_html($field, $section);
367 | }else{
368 | $field_html .= THWEPO_Utils_Field::prepare_field_html($field, $section);
369 | }
370 | }
371 | }
372 |
373 | if(!empty($field_html)){
374 | $cssclass = THWEPO_Utils::convert_cssclass_string($section->get_property('cssclass'));
375 | $cssclass .= $product_type ? ' thwepo_'.$product_type : '';
376 |
377 | $conditions_data = self::get_ajax_conditions_data($section);
378 | if($conditions_data){
379 | $cssclass .= empty($cssclass) ? 'thwepo-conditional-section' : ' thwepo-conditional-section';
380 | }
381 |
382 | $section_html .= '';
386 | }
387 |
388 | if(!empty($field_html_hidden)){
389 | $section_html .= $field_html_hidden;
390 | }
391 | return $section_html;
392 | }
393 |
394 | public static function prepare_title_html($section){
395 | $title_html = '';
396 | if($section->get_property('title')){
397 | $title_class = THWEPO_Utils::convert_cssclass_string($section->get_property('title_class'));
398 | $title_type = $section->get_property('title_type') ? $section->get_property('title_type') : 'label';
399 | $title_style = $section->get_property('title_color') ? 'style="color:'.$section->get_property('title_color').';"' : '';
400 |
401 | $title_html .= '<'.$title_type.' class="'.$title_class.'" '.$title_style.'>';
402 | $title_html .= THWEPO_i18n::esc_html__t($section->get_property('title'));
403 | $title_html .= ''.$title_type.'>';
404 | }
405 |
406 | $subtitle_html = '';
407 | if($section->get_property('subtitle')){
408 | $subtitle_class = THWEPO_Utils::convert_cssclass_string($section->get_property('subtitle_class'));
409 | $subtitle_type = $section->get_property('subtitle_type') ? $section->get_property('subtitle_type') : 'span';
410 | $subtitle_style = $section->get_property('subtitle_color') ? 'color:'.$section->get_property('subtitle_color').';' : '';
411 | $subtitle_style = 'style="font-size:80%; '.$subtitle_style.'"';
412 |
413 | $subtitle_html .= !empty($title_html) ? '
' : '';
414 | $subtitle_html .= '<'.$subtitle_type.' class="'.$subtitle_class.'" '.$subtitle_style.'>';
415 | $subtitle_html .= THWEPO_i18n::esc_html__t($section->get_property('subtitle'));
416 | $subtitle_html .= ''.$subtitle_type.'>';
417 | }
418 |
419 | $html = $title_html;
420 | if(!empty($subtitle_html)){
421 | $html .= $subtitle_html;
422 | }
423 |
424 | if(!empty($html)){
425 | $html = ''.$html.' |
';
426 | }else{
427 | $html = ' |
';
428 | }
429 | return $html;
430 | }
431 |
432 | private static function get_ajax_conditions_data($section){
433 | $data_str = false;
434 | if($section->get_property('conditional_rules_ajax_json')){
435 | $rules_action = $section->get_property('rules_action_ajax') ? $section->get_property('rules_action_ajax') : 'show';
436 | $rules = urldecode($section->get_property('conditional_rules_ajax_json'));
437 | $rules = esc_js($rules);
438 |
439 | $data_str = 'id="'.$section->name.'" data-rules="'. $rules .'" data-rules-action="'. $rules_action .'" data-rules-elm="section"';
440 | }
441 | return $data_str;
442 | }
443 | }
444 |
445 | endif;
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | \n"
13 | "Language-Team: LANGUAGE \n"
14 |
15 | msgid "WooCommerce Extra Product Options"
16 | msgstr ""
17 |
18 | msgid "WooCommerce Extra Product Options Pro"
19 | msgstr ""
20 |
21 | msgid "Documentation"
22 | msgstr ""
23 |
24 | msgid "Dismiss"
25 | msgstr ""
26 |
27 | msgid "Design woocommerce Product form in your own way, customize Product fields(Add, Edit, Delete and re arrange fields)."
28 | msgstr ""
29 |
30 | msgid "Extra Product Option"
31 | msgstr ""
32 |
33 | msgid "Product Options"
34 | msgstr ""
35 |
36 | msgid "Add new section"
37 | msgstr ""
38 |
39 | msgid "Delete Section"
40 | msgstr ""
41 |
42 | msgid "Edit Section"
43 | msgstr ""
44 |
45 | msgid "+ Add field"
46 | msgstr ""
47 |
48 | msgid "Remove"
49 | msgstr ""
50 |
51 | msgid "Enable"
52 | msgstr ""
53 |
54 | msgid "Disable"
55 | msgstr ""
56 |
57 | msgid "Save changes"
58 | msgstr ""
59 |
60 | msgid "Reset to default fields"
61 | msgstr ""
62 |
63 | msgid "Your changes were not saved due to an error (or you made none!)."
64 | msgstr ""
65 |
66 | msgid "Your changes were not saved due to no fields found."
67 | msgstr ""
68 |
69 | msgid "Your changes were saved."
70 | msgstr ""
71 |
72 | msgid "Name"
73 | msgstr ""
74 |
75 | msgid "Type"
76 | msgstr ""
77 |
78 | msgid "Label"
79 | msgstr ""
80 |
81 | msgid "Placeholder"
82 | msgstr ""
83 |
84 | msgid "Validation Rules"
85 | msgstr ""
86 |
87 | msgid "Required"
88 | msgstr ""
89 |
90 | msgid "Enabled"
91 | msgstr ""
92 |
93 | msgid "Edit"
94 | msgstr ""
95 |
96 | msgid "Create New Section"
97 | msgstr ""
98 |
99 | msgid "New section added successfully."
100 | msgstr ""
101 |
102 | msgid "New section not added due to an error."
103 | msgstr ""
104 |
105 | msgid "Section details updated successfully."
106 | msgstr ""
107 |
108 | msgid "Section details not updated due to an error."
109 | msgstr ""
110 |
111 | msgid "Section removed successfully."
112 | msgstr ""
113 |
114 | msgid "Section not removed due to an error."
115 | msgstr ""
116 |
117 | msgid "Name/ID"
118 | msgstr ""
119 |
120 | msgid "Display Position"
121 | msgstr ""
122 |
123 | msgid "CSS Class"
124 | msgstr ""
125 |
126 | msgid "Show section title in product page."
127 | msgstr ""
128 |
129 | msgid "Title"
130 | msgstr ""
131 |
132 | msgid "Title Position"
133 | msgstr ""
134 |
135 | msgid "Title Type"
136 | msgstr ""
137 |
138 | msgid "Title Color"
139 | msgstr ""
140 |
141 | msgid "Title Class"
142 | msgstr ""
143 |
144 | msgid "Subtitle"
145 | msgstr ""
146 |
147 | msgid "Subtitle Type"
148 | msgstr ""
149 |
150 | msgid "Subtitle Color"
151 | msgstr ""
152 |
153 | msgid "Subtitle Class"
154 | msgstr ""
155 |
156 | msgid "Add subtitle"
157 | msgstr ""
158 |
159 | msgid "Before Add To Cart Button"
160 | msgstr ""
161 |
162 | msgid "After Add To Cart Button"
163 | msgstr ""
164 |
165 | msgid "New Product Field"
166 | msgstr ""
167 |
168 | msgid "General Properties"
169 | msgstr ""
170 |
171 | msgid "Conditional Rules"
172 | msgstr ""
173 |
174 | msgid "Field Type"
175 | msgstr ""
176 |
177 | msgid "Default Value"
178 | msgstr ""
179 |
180 | msgid "Validation"
181 | msgstr ""
182 |
183 | msgid "Price"
184 | msgstr ""
185 |
186 | msgid "Unit"
187 | msgstr ""
188 |
189 | msgid "Price Type"
190 | msgstr ""
191 |
192 | msgid "Min. Length"
193 | msgstr ""
194 |
195 | msgid "Max. Length"
196 | msgstr ""
197 |
198 | msgid "Default Date"
199 | msgstr ""
200 |
201 | msgid "Date Format"
202 | msgstr ""
203 |
204 | msgid "Min. Date"
205 | msgstr ""
206 |
207 | msgid "Max. Date"
208 | msgstr ""
209 |
210 | msgid "Year Range"
211 | msgstr ""
212 |
213 | msgid "Number Of Months"
214 | msgstr ""
215 |
216 | msgid "Disabled Days"
217 | msgstr ""
218 |
219 | msgid "Disabled Dates"
220 | msgstr ""
221 |
222 | msgid "Leave empty for today's date"
223 | msgstr ""
224 |
225 | msgid "The minimum selectable date"
226 | msgstr ""
227 |
228 | msgid "The maximum selectable date"
229 | msgstr ""
230 |
231 | msgid "Select days to disable"
232 | msgstr ""
233 |
234 | msgid "Seperate dates with comma"
235 | msgstr ""
236 |
237 | msgid "Min. Time"
238 | msgstr ""
239 |
240 | msgid "Max. Time"
241 | msgstr ""
242 |
243 | msgid "Time Step"
244 | msgstr ""
245 |
246 | msgid "Time Format"
247 | msgstr ""
248 |
249 | msgid "Specify a date in the current dateFormat, or number of days from today (e.g. +7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '+1m +7d'), or leave empty for today."
250 | msgstr ""
251 |
252 | msgid "The format for parsed and displayed dates."
253 | msgstr ""
254 |
255 | msgid "The minimum selectable date. Specify a date in the current dateFormat, or number of days from today (e.g. -7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '-1m -7d'), or leave empty for no minimum limit."
256 | msgstr ""
257 |
258 | msgid "The maximum selectable date. Specify a date in the current dateFormat, or number of days from today (e.g. +7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '+1m +7d'), or leave empty for no maximum limit."
259 | msgstr ""
260 |
261 | msgid "The range of years displayed in the year drop-down: either relative to today's year ('-nn:+nn' e.g. -5:+3), relative to the currently selected year ('c-nn:c+nn' e.g. c-10:c+10), absolute ('nnnn:nnnn' e.g. 2002:2012), or combinations of these formats ('nnnn:+nn' e.g. 2002:+3). Note that this option only affects what appears in the drop-down, to restrict which dates may be selected use the minDate and/or maxDate options."
262 | msgstr ""
263 |
264 | msgid "The number of months to show at once"
265 | msgstr ""
266 |
267 | msgid "Specify dates in yyyy-mm-dd format separated by comma."
268 | msgstr ""
269 |
270 | msgid "Show"
271 | msgstr ""
272 |
273 | msgid "Hide"
274 | msgstr ""
275 |
276 | msgid "field if all below conditions are met."
277 | msgstr ""
278 |
279 | msgid "Product"
280 | msgstr ""
281 |
282 | msgid "Category"
283 | msgstr ""
284 |
285 | msgid "Equals to/ In"
286 | msgstr ""
287 |
288 | msgid "Not Equals to/ Not in"
289 | msgstr ""
290 |
291 | msgid "AND"
292 | msgstr ""
293 |
294 | msgid "OR"
295 | msgstr ""
296 |
297 | msgid "(%s) is not a valid number."
298 | msgstr ""
299 |
300 | msgid "(%s) is not a valid email address."
301 | msgstr ""
302 |
303 | msgid "Please enter a value for %s"
304 | msgstr ""
--------------------------------------------------------------------------------
/public/assets/css/thwepo-public.min.css:
--------------------------------------------------------------------------------
1 | .woocommerce div.product form.cart table.extra-options,table.extra-options{width:100%}.single-product div.product table.extra-options th,table.extra-options td{background-color:transparent}.single-product div.product table.extra-options th.leftside,table.extra-options td.leftside{display:table-cell}.single-product div.product table.extra-options th.above,table.extra-options td.above{display:list-item;padding:0;list-style:none}table.extra-options .label-tag,table.extra-options .sublabel-tag{display:inline-block}table.extra-options .required{border-bottom:0!important;color:red;text-decoration:none}table.extra-options select{min-width:80px}table.extra-options input[type=checkbox]{vertical-align:top;margin-top:5px}table.extra-options .label-wrapper-checkbox{padding:0;margin:0;display:inline-block}.font-size-80-perc{font-size:80%!important}.font-size-100-perc{font-size:100%!important}.display-table-cell{display:table-cell!important}.display-list-item{display:list-item!important}.label-field-cell{display:table-cell!important}.no-border,.no-border td{border:0!important}.strong{font-weight:700!important}.cell-p-0 td,.cell-p-0 th,.p-0{padding:0!important}.cell-p-5 td,.cell-p-5 th,.p-5{padding:5!important}.cell-p-10 td,.cell-p-10 th,.p-10{padding:10!important}.ui-widget-content{z-index:99999!important}.ui-datepicker .ui-datepicker-title select{color:initial;padding-right:0;display:inline-block;height:auto}.ui-datepicker .ui-datepicker-buttonpane button{text-transform:capitalize;letter-spacing:normal;line-height:initial;min-height:0}.select2-results .select2-results__option{white-space:nowrap}.select2-container{z-index:99999}.iris-picker{z-index:100;display:none;position:absolute!important;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:0 0!important}.iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.thwepo-colorpicker-preview{padding:10px 22px 12px;border:1px solid rgba(0,0,0,.125);background-color:#FFF}.thwepo-color-picker{border-left:0}.thwepo-colorpicker-preview.thplwepo-round{border-radius:50%;margin-right:12px}.thwepo_tooltip{font-size:inherit;color:#fff;--tooltip-bg:#333;display:inline-block;vertical-align:middle;position:relative;height:100%;margin-left:3px;z-index:999999}.thwepo_tooltip img{padding:0;vertical-align:middle;cursor:help;border:none;height:16px;width:16px}.thwepo_tooltip:hover:after{font-size:inherit;color:inherit;background:#333;background:rgba(0,0,0,1);border-radius:5px;bottom:26px;content:attr(title);left:-100px;padding:10px 15px;position:absolute;z-index:9998;width:350px;background-color:var(--tooltip-bg)}.thwepo_tooltip:hover:before{border:solid;border-color:#000 transparent;border-color:var(--tooltip-bg) transparent;border-width:6px 6px 0;bottom:20px;content:"";left:50%;position:absolute;z-index:9999}
--------------------------------------------------------------------------------
/public/assets/js/timepicker/jquery.timepicker.css:
--------------------------------------------------------------------------------
1 | .ui-timepicker-wrapper {
2 | overflow-y: auto;
3 | height: 150px;
4 | width: 6.5em;
5 | background: #fff;
6 | border: 1px solid #ddd;
7 | -webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);
8 | -moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);
9 | box-shadow:0 5px 10px rgba(0,0,0,0.2);
10 | outline: none;
11 | z-index: 10001;
12 | margin: 0;
13 | }
14 |
15 | .ui-timepicker-wrapper.ui-timepicker-with-duration {
16 | width: 13em;
17 | }
18 |
19 | .ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30,
20 | .ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 {
21 | width: 11em;
22 | }
23 |
24 | .ui-timepicker-list {
25 | margin: 0;
26 | padding: 0;
27 | list-style: none;
28 | }
29 |
30 | .ui-timepicker-duration {
31 | margin-left: 5px; color: #888;
32 | }
33 |
34 | .ui-timepicker-list:hover .ui-timepicker-duration {
35 | color: #888;
36 | }
37 |
38 | .ui-timepicker-list li {
39 | padding: 3px 0 3px 5px;
40 | cursor: pointer;
41 | white-space: nowrap;
42 | color: #000;
43 | list-style: none;
44 | margin: 0;
45 | }
46 |
47 | .ui-timepicker-list:hover .ui-timepicker-selected {
48 | background: #fff; color: #000;
49 | }
50 |
51 | li.ui-timepicker-selected,
52 | .ui-timepicker-list li:hover,
53 | .ui-timepicker-list .ui-timepicker-selected:hover {
54 | background: #1980EC; color: #fff;
55 | }
56 |
57 | li.ui-timepicker-selected .ui-timepicker-duration,
58 | .ui-timepicker-list li:hover .ui-timepicker-duration {
59 | color: #ccc;
60 | }
61 |
62 | .ui-timepicker-list li.ui-timepicker-disabled,
63 | .ui-timepicker-list li.ui-timepicker-disabled:hover,
64 | .ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
65 | color: #888;
66 | cursor: default;
67 | }
68 |
69 | .ui-timepicker-list li.ui-timepicker-disabled:hover,
70 | .ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
71 | background: #f2f2f2;
72 | }
73 |
--------------------------------------------------------------------------------
/public/assets/js/timepicker/jquery.timepicker.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jquery-timepicker v1.8.5 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation.
3 | * Copyright (c) 2015 Jon Thornton - http://jonthornton.github.com/jquery-timepicker/
4 | * License: MIT
5 | */
6 |
7 | !function(a){"object"==typeof exports&&exports&&"object"==typeof module&&module&&module.exports===exports?a(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){function b(a){var b=a[0];return b.offsetWidth>0&&b.offsetHeight>0}function c(b){if(b.minTime&&(b.minTime=u(b.minTime)),b.maxTime&&(b.maxTime=u(b.maxTime)),b.durationTime&&"function"!=typeof b.durationTime&&(b.durationTime=u(b.durationTime)),"now"==b.scrollDefault)b.scrollDefault=function(){return b.roundingFunction(u(new Date),b)};else if(b.scrollDefault&&"function"!=typeof b.scrollDefault){var c=b.scrollDefault;b.scrollDefault=function(){return b.roundingFunction(u(c),b)}}else b.minTime&&(b.scrollDefault=function(){return b.roundingFunction(b.minTime,b)});if("string"===a.type(b.timeFormat)&&b.timeFormat.match(/[gh]/)&&(b._twelveHourTime=!0),b.showOnFocus===!1&&-1!=b.showOn.indexOf("focus")&&b.showOn.splice(b.showOn.indexOf("focus"),1),b.disableTimeRanges.length>0){for(var d in b.disableTimeRanges)b.disableTimeRanges[d]=[u(b.disableTimeRanges[d][0]),u(b.disableTimeRanges[d][1])];b.disableTimeRanges=b.disableTimeRanges.sort(function(a,b){return a[0]-b[0]});for(var d=b.disableTimeRanges.length-1;d>0;d--)b.disableTimeRanges[d][0]<=b.disableTimeRanges[d-1][1]&&(b.disableTimeRanges[d-1]=[Math.min(b.disableTimeRanges[d][0],b.disableTimeRanges[d-1][0]),Math.max(b.disableTimeRanges[d][1],b.disableTimeRanges[d-1][1])],b.disableTimeRanges.splice(d,1))}return b}function d(b){var c=b.data("timepicker-settings"),d=b.data("timepicker-list");if(d&&d.length&&(d.remove(),b.data("timepicker-list",!1)),c.useSelect){d=a("",{"class":"ui-timepicker-select"});var g=d}else{d=a("",{"class":"ui-timepicker-list"});var g=a("",{"class":"ui-timepicker-wrapper",tabindex:-1});g.css({display:"none",position:"absolute"}).append(d)}if(c.noneOption)if(c.noneOption===!0&&(c.noneOption=c.useSelect?"Time...":"None"),a.isArray(c.noneOption)){for(var h in c.noneOption)if(parseInt(h,10)==h){var i=e(c.noneOption[h],c.useSelect);d.append(i)}}else{var i=e(c.noneOption,c.useSelect);d.append(i)}if(c.className&&g.addClass(c.className),(null!==c.minTime||null!==c.durationTime)&&c.showDuration){"function"==typeof c.step?"function":c.step;g.addClass("ui-timepicker-with-duration"),g.addClass("ui-timepicker-step-"+c.step)}var k=c.minTime;"function"==typeof c.durationTime?k=u(c.durationTime()):null!==c.durationTime&&(k=c.durationTime);var m=null!==c.minTime?c.minTime:0,n=null!==c.maxTime?c.maxTime:m+w-1;m>n&&(n+=w),n===w-1&&"string"===a.type(c.timeFormat)&&c.show2400&&(n=w);var p=c.disableTimeRanges,q=0,v=p.length,x=c.step;"function"!=typeof x&&(x=function(){return c.step});for(var h=m,z=0;n>=h;z++,h+=60*x(z)){var A=h,B=t(A,c);if(c.useSelect){var C=a("",{value:B});C.text(B)}else{var C=a("");C.data("time",86400>=A?A:A%86400),C.text(B)}if((null!==c.minTime||null!==c.durationTime)&&c.showDuration){var D=s(h-k,c.step);if(c.useSelect)C.text(C.text()+" ("+D+")");else{var E=a("",{"class":"ui-timepicker-duration"});E.text(" ("+D+")"),C.append(E)}}v>q&&(A>=p[q][1]&&(q+=1),p[q]&&A>=p[q][0]&&A",{value:f,"class":e,text:d}):a("",{"class":e,text:d}).data("time",f)}function f(a,b){return a=b.roundingFunction(a,b),null!==a?t(a,b):void 0}function g(){return new Date(1970,1,1,0,0,0)}function h(b){var c=a(b.target),d=c.closest(".ui-timepicker-input");0===d.length&&0===c.closest(".ui-timepicker-wrapper").length&&(y.hide(),a(document).unbind(".ui-timepicker"),a(window).unbind(".ui-timepicker"))}function j(a){var b=a.data("timepicker-settings");return(window.navigator.msMaxTouchPoints||"ontouchstart"in document)&&b.disableTouchKeyboard}function k(b,c,d){if(!d&&0!==d)return!1;var e=b.data("timepicker-settings"),f=!1,d=e.roundingFunction(d,e);return c.find("li").each(function(b,c){var e=a(c);if("number"==typeof e.data("time"))return e.data("time")==d?(f=e,!1):void 0}),f}function l(a,b){b.find("li").removeClass("ui-timepicker-selected");var c=u(n(a),a.data("timepicker-settings"));if(null!==c){var d=k(a,b,c);if(d){var e=d.offset().top-b.offset().top;(e+d.outerHeight()>b.outerHeight()||0>e)&&b.scrollTop(b.scrollTop()+d.position().top-d.outerHeight()),d.addClass("ui-timepicker-selected")}}}function m(b,c){if(""!==this.value&&"timepicker"!=c){var d=a(this);if(!d.is(":focus")||b&&"change"==b.type){var e=d.data("timepicker-settings"),f=u(this.value,e);if(null===f)return void d.trigger("timeFormatError");var g=!1;null!==e.minTime&&fe.maxTime&&(g=!0),a.each(e.disableTimeRanges,function(){return f>=this[0]&&f0?(f=a(c),!1):void 0}),f.addClass("ui-timepicker-selected")),!1;case 40:return f=e.find(".ui-timepicker-selected"),0===f.length?(e.find("li").each(function(b,c){return a(c).position().top>0?(f=a(c),!1):void 0}),f.addClass("ui-timepicker-selected")):f.is(":last-child")||(f.removeClass("ui-timepicker-selected"),f.next().addClass("ui-timepicker-selected"),f.next().position().top+2*f.outerHeight()>e.outerHeight()&&e.scrollTop(e.scrollTop()+f.outerHeight())),!1;case 27:e.find("li").removeClass("ui-timepicker-selected"),y.hide();break;case 9:y.hide();break;default:return!0}}function q(c){var d=a(this),e=d.data("timepicker-list"),f=d.data("timepicker-settings");if(!e||!b(e)||f.disableTextInput)return!0;switch(c.keyCode){case 96:case 97:case 98:case 99:case 100:case 101:case 102:case 103:case 104:case 105:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 65:case 77:case 80:case 186:case 8:case 46:f.typeaheadHighlight?l(d,e):e.hide()}}function r(a){var b=a.data("timepicker-settings"),c=a.data("timepicker-list"),d=null,e=c.find(".ui-timepicker-selected");return e.hasClass("ui-timepicker-disabled")?!1:(e.length&&(d=e.data("time")),null!==d&&("string"!=typeof d&&(d=t(d,b)),o(a,d,"select")),!0)}function s(a,b){a=Math.abs(a);var c,d,e=Math.round(a/60),f=[];return 60>e?f=[e,x.mins]:(c=Math.floor(e/60),d=e%60,30==b&&30==d&&(c+=x.decimal+5),f.push(c),f.push(1==c?x.hr:x.hrs),30!=b&&d&&(f.push(d),f.push(x.mins))),f.join(" ")}function t(b,c){if(null===b)return null;var d=new Date(v.valueOf()+1e3*b);if(isNaN(d.getTime()))return null;if("function"===a.type(c.timeFormat))return c.timeFormat(d);for(var e,f,g="",h=0;h11?x.pm:x.am;break;case"A":g+=d.getHours()>11?x.PM:x.AM;break;case"g":e=d.getHours()%12,g+=0===e?"12":e;break;case"G":e=d.getHours(),b===w&&(e=24),g+=e;break;case"h":e=d.getHours()%12,0!==e&&10>e&&(e="0"+e),g+=0===e?"12":e;break;case"H":e=d.getHours(),b===w&&(e=c.show2400?24:0),g+=e>9?e:"0"+e;break;case"i":var i=d.getMinutes();g+=i>9?i:"0"+i;break;case"s":b=d.getSeconds(),g+=b>9?b:"0"+b;break;case"\\":h++,g+=c.timeFormat.charAt(h);break;default:g+=f}return g}function u(a,b){if(""===a)return null;if(!a||a+0==a)return a;if("object"==typeof a)return 3600*a.getHours()+60*a.getMinutes()+a.getSeconds();a=a.toLowerCase().replace(/[\s\.]/g,""),("a"==a.slice(-1)||"p"==a.slice(-1))&&(a+="m");var c="("+x.am.replace(".","")+"|"+x.pm.replace(".","")+"|"+x.AM.replace(".","")+"|"+x.PM.replace(".","")+")?",d=new RegExp("^"+c+"([0-2]?[0-9])\\W?([0-5][0-9])?\\W?([0-5][0-9])?"+c+"$"),e=a.match(d);if(!e)return null;var f=parseInt(1*e[2],10),g=e[1]||e[5],h=f;if(12>=f&&g){var i=g==x.pm||g==x.PM;h=12==f?i?12:0:f+(i?12:0)}var j=1*e[3]||0,k=1*e[4]||0,l=3600*h+60*j+k;if(12>f&&!g&&b&&b._twelveHourTime&&b.scrollDefault){var m=l-b.scrollDefault();0>m&&m>=w/-2&&(l=(l+w/2)%w)}return l}var v=g(),w=86400,x={am:"am",pm:"pm",AM:"AM",PM:"PM",decimal:".",mins:"mins",hr:"hr",hrs:"hrs"},y={init:function(b){return this.each(function(){var e=a(this),f=[];for(var g in a.fn.timepicker.defaults)e.data(g)&&(f[g]=e.data(g));var h=a.extend({},a.fn.timepicker.defaults,f,b);if(h.lang&&(x=a.extend(x,h.lang)),h=c(h),e.data("timepicker-settings",h),e.addClass("ui-timepicker-input"),h.useSelect)d(e);else{if(e.prop("autocomplete","off"),h.showOn)for(i in h.showOn)e.on(h.showOn[i]+".timepicker",y.show);e.on("change.timepicker",m),e.on("keydown.timepicker",p),e.on("keyup.timepicker",q),h.disableTextInput&&e.on("keypress.timepicker",function(a){a.preventDefault()}),m.call(e.get(0))}})},show:function(c){var e=a(this),f=e.data("timepicker-settings");if(c&&c.preventDefault(),f.useSelect)return void e.data("timepicker-list").focus();j(e)&&e.blur();var g=e.data("timepicker-list");if(!e.prop("readonly")&&(g&&0!==g.length&&"function"!=typeof f.durationTime||(d(e),g=e.data("timepicker-list")),!b(g))){e.data("ui-timepicker-value",e.val()),l(e,g),y.hide(),g.show();var i={};f.orientation.match(/r/)?i.left=e.offset().left+e.outerWidth()-g.outerWidth()+parseInt(g.css("marginLeft").replace("px",""),10):i.left=e.offset().left+parseInt(g.css("marginLeft").replace("px",""),10);var m;m=f.orientation.match(/t/)?"t":f.orientation.match(/b/)?"b":e.offset().top+e.outerHeight(!0)+g.outerHeight()>a(window).height()+a(window).scrollTop()?"t":"b","t"==m?(g.addClass("ui-timepicker-positioned-top"),i.top=e.offset().top-g.outerHeight()+parseInt(g.css("marginTop").replace("px",""),10)):(g.removeClass("ui-timepicker-positioned-top"),i.top=e.offset().top+e.outerHeight()+parseInt(g.css("marginTop").replace("px",""),10)),g.offset(i);var o=g.find(".ui-timepicker-selected");if(!o.length){var p=u(n(e));null!==p?o=k(e,g,p):f.scrollDefault&&(o=k(e,g,f.scrollDefault()))}if(o&&o.length){var q=g.scrollTop()+o.position().top-o.outerHeight();g.scrollTop(q)}else g.scrollTop(0);return f.stopScrollPropagation&&a(document).on("wheel.ui-timepicker",".ui-timepicker-wrapper",function(b){b.preventDefault();var c=a(this).scrollTop();a(this).scrollTop(c+b.originalEvent.deltaY)}),a(document).on("touchstart.ui-timepicker mousedown.ui-timepicker",h),a(window).on("resize.ui-timepicker",h),f.closeOnWindowScroll&&a(document).on("scroll.ui-timepicker",h),e.trigger("showTimepicker"),this}},hide:function(c){var d=a(this),e=d.data("timepicker-settings");return e&&e.useSelect&&d.blur(),a(".ui-timepicker-wrapper").each(function(){var c=a(this);if(b(c)){var d=c.data("timepicker-input"),e=d.data("timepicker-settings");e&&e.selectOnBlur&&r(d),c.hide(),d.trigger("hideTimepicker")}}),this},option:function(b,e){return this.each(function(){var f=a(this),g=f.data("timepicker-settings"),h=f.data("timepicker-list");if("object"==typeof b)g=a.extend(g,b);else if("string"==typeof b&&"undefined"!=typeof e)g[b]=e;else if("string"==typeof b)return g[b];g=c(g),f.data("timepicker-settings",g),h&&(h.remove(),f.data("timepicker-list",!1)),g.useSelect&&d(f)})},getSecondsFromMidnight:function(){return u(n(this))},getTime:function(a){var b=this,c=n(b);if(!c)return null;var d=u(c);if(null===d)return null;a||(a=v);var e=new Date(a);return e.setHours(d/3600),e.setMinutes(d%3600/60),e.setSeconds(d%60),e.setMilliseconds(0),e},setTime:function(a){var b=this,c=b.data("timepicker-settings");if(c.forceRoundTime)var d=f(u(a),c);else var d=t(u(a),c);return a&&null===d&&c.noneOption&&(d=a),o(b,d),b.data("timepicker-list")&&l(b,b.data("timepicker-list")),this},remove:function(){var a=this;if(a.hasClass("ui-timepicker-input")){var b=a.data("timepicker-settings");return a.removeAttr("autocomplete","off"),a.removeClass("ui-timepicker-input"),a.removeData("timepicker-settings"),a.off(".timepicker"),a.data("timepicker-list")&&a.data("timepicker-list").remove(),b.useSelect&&a.show(),a.removeData("timepicker-list"),this}}};a.fn.timepicker=function(b){return this.length?y[b]?this.hasClass("ui-timepicker-input")?y[b].apply(this,Array.prototype.slice.call(arguments,1)):this:"object"!=typeof b&&b?void a.error("Method "+b+" does not exist on jQuery.timepicker"):y.init.apply(this,arguments):this},a.fn.timepicker.defaults={appendTo:"body",className:null,closeOnWindowScroll:!1,disableTextInput:!1,disableTimeRanges:[],disableTouchKeyboard:!1,durationTime:null,forceRoundTime:!1,maxTime:null,minTime:null,noneOption:!1,orientation:"l",roundingFunction:function(a,b){if(null===a)return null;var c=a%(60*b.step);return c>=30*b.step?a+=60*b.step-c:a-=c,a},scrollDefault:null,selectOnBlur:!1,show2400:!1,showDuration:!1,showOn:["click","focus"],showOnFocus:!0,step:30,stopScrollPropagation:!1,timeFormat:"g:ia",typeaheadHighlight:!0,useSelect:!1}});
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | get your license key.';
60 | $title_note = sprintf($title_note, $help_doc_url);
61 | return $title_note;
62 | }
63 |
64 | function thwepo_license_page_url($url, $prefix){
65 | $url = 'edit.php?post_type=product&page=th_extra_product_options_pro&tab=license_settings';
66 | return admin_url($url);
67 | }
68 |
69 | function init_auto_updater_thwepo(){
70 | if(!class_exists('THWEPO_License_Manager') ) {
71 | add_filter('thlm_license_form_title_note_woocommerce_extra_product_options', 'thwepo_license_form_title_note');
72 | add_filter('thlm_license_page_url_woocommerce_extra_product_options', 'thwepo_license_page_url', 10, 2);
73 | add_filter('thlm_enable_default_license_page', '__return_false');
74 |
75 | require_once( plugin_dir_path( __FILE__ ) . 'class-thwepo-license-manager.php' );
76 | $api_url = 'https://themehigh.com/';
77 | THWEPO_License_Manager::instance(__FILE__, $api_url, 'plugin', THWEPO_SOFTWARE_TITLE);
78 | }
79 | }
80 | init_auto_updater_thwepo();
81 |
82 | /**
83 | * The core plugin class that is used to define internationalization,
84 | * admin-specific hooks, and public-facing site hooks.
85 | */
86 | require plugin_dir_path( __FILE__ ) . 'includes/class-thwepo.php';
87 |
88 | /**
89 | * Begins execution of the plugin.
90 | */
91 | function run_thwepo() {
92 | $plugin = new THWEPO();
93 | $plugin->run();
94 | }
95 | run_thwepo();
96 | }
--------------------------------------------------------------------------------