Variation Swatches for WooCommerce - Version 1.0.11

Version Description

  • Compatible with latest wordpress.
Download this release

Release Info

Developer themealien
Plugin Icon 128x128 Variation Swatches for WooCommerce
Version 1.0.11
Comparing to
See all releases

Code changes from version 1.0.10 to 1.0.11

assets/css/admin.css CHANGED
@@ -1,62 +1,62 @@
1
- .swatch-preview {
2
- width: 44px;
3
- height: 44px;
4
- line-height: 44px;
5
- text-align: center;
6
- font-weight: 700;
7
- border: 1px solid #ccc;
8
- }
9
-
10
- .tawcvs-modal-container {
11
- position: relative;
12
- display: none;
13
- }
14
-
15
- .tawcvs-modal {
16
- transform: translate(-50%, -50%);
17
- position: fixed;
18
- top: 50%;
19
- left: 50%;
20
- width: 360px;
21
- max-width: 90%;
22
- z-index: 159990;
23
- background-color: #fcfcfc;
24
- }
25
-
26
- .tawcvs-modal input.error {
27
- border-color: #dc3232;
28
- }
29
-
30
- .tawcvs-modal-header,
31
- .tawcvs-modal-content,
32
- .tawcvs-modal-footer {
33
- padding: 20px;
34
- }
35
-
36
- .tawcvs-modal-header {
37
- padding-top: 0;
38
- padding-bottom: 0;
39
- }
40
-
41
- .tawcvs-modal-content {
42
- border-top: 1px solid #ddd;
43
- border-bottom: 1px solid #ddd;
44
- background-color: #fff;
45
- }
46
-
47
- .tawcvs-modal-footer {
48
- text-align: right;
49
- }
50
-
51
- .tawcvs-modal-footer .message,
52
- .tawcvs-modal-footer .spinner {
53
- float: left;
54
- }
55
-
56
- .tawcvs-modal-footer .message.error {
57
- color: #dc3232;
58
- }
59
-
60
- .tawcvs-modal-footer .message.success {
61
- color: #46b450;
62
- }
1
+ .swatch-preview {
2
+ width: 44px;
3
+ height: 44px;
4
+ line-height: 44px;
5
+ text-align: center;
6
+ font-weight: 700;
7
+ border: 1px solid #ccc;
8
+ }
9
+
10
+ .tawcvs-modal-container {
11
+ position: relative;
12
+ display: none;
13
+ }
14
+
15
+ .tawcvs-modal {
16
+ transform: translate(-50%, -50%);
17
+ position: fixed;
18
+ top: 50%;
19
+ left: 50%;
20
+ width: 360px;
21
+ max-width: 90%;
22
+ z-index: 159990;
23
+ background-color: #fcfcfc;
24
+ }
25
+
26
+ .tawcvs-modal input.error {
27
+ border-color: #dc3232;
28
+ }
29
+
30
+ .tawcvs-modal-header,
31
+ .tawcvs-modal-content,
32
+ .tawcvs-modal-footer {
33
+ padding: 20px;
34
+ }
35
+
36
+ .tawcvs-modal-header {
37
+ padding-top: 0;
38
+ padding-bottom: 0;
39
+ }
40
+
41
+ .tawcvs-modal-content {
42
+ border-top: 1px solid #ddd;
43
+ border-bottom: 1px solid #ddd;
44
+ background-color: #fff;
45
+ }
46
+
47
+ .tawcvs-modal-footer {
48
+ text-align: right;
49
+ }
50
+
51
+ .tawcvs-modal-footer .message,
52
+ .tawcvs-modal-footer .spinner {
53
+ float: left;
54
+ }
55
+
56
+ .tawcvs-modal-footer .message.error {
57
+ color: #dc3232;
58
+ }
59
+
60
+ .tawcvs-modal-footer .message.success {
61
+ color: #46b450;
62
+ }
assets/css/frontend.css CHANGED
@@ -1,134 +1,134 @@
1
- .hidden {
2
- display: none !important;
3
- visibility: hidden !important;
4
- }
5
-
6
- .tawcvs-swatches {
7
- padding: 5px;
8
- }
9
-
10
- .tawcvs-swatches .swatch {
11
- -webkit-transition: all 0.3s;
12
- -moz-transition: all 0.3s;
13
- -ms-transition: all 0.3s;
14
- -o-transition: all 0.3s;
15
- transition: all 0.3s;
16
- -webkit-border-radius: 50%;
17
- -moz-border-radius: 50%;
18
- border-radius: 50%;
19
- display: inline-block;
20
- width: 30px;
21
- height: 30px;
22
- line-height: 28px;
23
- text-align: center;
24
- margin-right: 15px;
25
- margin-bottom: 15px;
26
- cursor: pointer;
27
- border: 2px solid transparent;
28
- position: relative;
29
- white-space: nowrap;
30
- }
31
-
32
- .tawcvs-swatches .swatch.selected {
33
- border-color: #999;
34
- }
35
-
36
- .tawcvs-swatches .swatch.disabled {
37
- cursor: default;
38
- opacity: 0.1 !important;
39
- }
40
-
41
- .tawcvs-swatches .swatch.disabled .swatch__tooltip {
42
- display: none;
43
- }
44
-
45
- .tawcvs-swatches .swatch-color {
46
- text-indent: -9999em;
47
- border: 2px solid #ccc;
48
- }
49
-
50
- .tawcvs-swatches .swatch-color.selected {
51
- border-color: #333;
52
- }
53
-
54
- .tawcvs-swatches .swatch-color.selected:before {
55
- -webkit-transform: translate(-50%, -50%) rotate(45deg);
56
- -moz-transform: translate(-50%, -50%) rotate(45deg);
57
- transform: translate(-50%, -50%) rotate(45deg);
58
- content: "";
59
- width: 6px;
60
- height: 10px;
61
- display: block;
62
- border: solid #eee;
63
- border-width: 0 2px 2px 0;
64
- position: absolute;
65
- top: 50%;
66
- left: 50%;
67
- margin: -2px -2px 0 0;
68
- }
69
-
70
- .tawcvs-swatches .swatch-label {
71
- font-size: 14px;
72
- background-color: #f1f1f1;
73
- }
74
-
75
- .tawcvs-swatches .swatch-image {
76
- font-size: 0;
77
- }
78
-
79
- .tawcvs-swatches .swatch-image img {
80
- -webkit-border-radius: 50%;
81
- -moz-border-radius: 50%;
82
- border-radius: 50%;
83
- }
84
-
85
- .tawcvs-swatches .swatch-image .swatch__tooltip {
86
- font-size: 14px;
87
- }
88
-
89
- .tawcvs-swatches .swatch__tooltip {
90
- -webkit-transform: translate(-50%, -100%);
91
- -moz-transform: translate(-50%, -100%);
92
- transform: translate(-50%, -100%);
93
- -webkit-transition: all 0.3s;
94
- -moz-transition: all 0.3s;
95
- -ms-transition: all 0.3s;
96
- -o-transition: all 0.3s;
97
- transition: all 0.3s;
98
- -webkit-border-radius: 3px;
99
- -moz-border-radius: 3px;
100
- border-radius: 3px;
101
- position: absolute;
102
- left: 50%;
103
- top: 0;
104
- background: #333;
105
- z-index: 2;
106
- color: #fff;
107
- margin: -15px 0 0 0;
108
- padding: 5px 10px;
109
- text-indent: initial;
110
- font-size: 14px;
111
- font-weight: 500;
112
- opacity: 0;
113
- visibility: hidden;
114
- user-select: none;
115
- }
116
-
117
- .tawcvs-swatches .swatch__tooltip:after {
118
- -webkit-transform: rotate(45deg);
119
- -moz-transform: rotate(45deg);
120
- transform: rotate(45deg);
121
- content: "";
122
- position: absolute;
123
- width: 12px;
124
- height: 12px;
125
- background: #333;
126
- bottom: -4px;
127
- left: 50%;
128
- margin-left: -6px;
129
- }
130
- .tawcvs-swatches .swatch:hover .swatch__tooltip {
131
- opacity: 1;
132
- visibility: visible;
133
- user-select: auto;
134
- }
1
+ .hidden {
2
+ display: none !important;
3
+ visibility: hidden !important;
4
+ }
5
+
6
+ .tawcvs-swatches {
7
+ padding: 5px;
8
+ }
9
+
10
+ .tawcvs-swatches .swatch {
11
+ -webkit-transition: all 0.3s;
12
+ -moz-transition: all 0.3s;
13
+ -ms-transition: all 0.3s;
14
+ -o-transition: all 0.3s;
15
+ transition: all 0.3s;
16
+ -webkit-border-radius: 50%;
17
+ -moz-border-radius: 50%;
18
+ border-radius: 50%;
19
+ display: inline-block;
20
+ width: 30px;
21
+ height: 30px;
22
+ line-height: 28px;
23
+ text-align: center;
24
+ margin-right: 15px;
25
+ margin-bottom: 15px;
26
+ cursor: pointer;
27
+ border: 2px solid transparent;
28
+ position: relative;
29
+ white-space: nowrap;
30
+ }
31
+
32
+ .tawcvs-swatches .swatch.selected {
33
+ border-color: #999;
34
+ }
35
+
36
+ .tawcvs-swatches .swatch.disabled {
37
+ cursor: default;
38
+ opacity: 0.1 !important;
39
+ }
40
+
41
+ .tawcvs-swatches .swatch.disabled .swatch__tooltip {
42
+ display: none;
43
+ }
44
+
45
+ .tawcvs-swatches .swatch-color {
46
+ text-indent: -9999em;
47
+ border: 2px solid #ccc;
48
+ }
49
+
50
+ .tawcvs-swatches .swatch-color.selected {
51
+ border-color: #333;
52
+ }
53
+
54
+ .tawcvs-swatches .swatch-color.selected:before {
55
+ -webkit-transform: translate(-50%, -50%) rotate(45deg);
56
+ -moz-transform: translate(-50%, -50%) rotate(45deg);
57
+ transform: translate(-50%, -50%) rotate(45deg);
58
+ content: "";
59
+ width: 6px;
60
+ height: 10px;
61
+ display: block;
62
+ border: solid #eee;
63
+ border-width: 0 2px 2px 0;
64
+ position: absolute;
65
+ top: 50%;
66
+ left: 50%;
67
+ margin: -2px -2px 0 0;
68
+ }
69
+
70
+ .tawcvs-swatches .swatch-label {
71
+ font-size: 14px;
72
+ background-color: #f1f1f1;
73
+ }
74
+
75
+ .tawcvs-swatches .swatch-image {
76
+ font-size: 0;
77
+ }
78
+
79
+ .tawcvs-swatches .swatch-image img {
80
+ -webkit-border-radius: 50%;
81
+ -moz-border-radius: 50%;
82
+ border-radius: 50%;
83
+ }
84
+
85
+ .tawcvs-swatches .swatch-image .swatch__tooltip {
86
+ font-size: 14px;
87
+ }
88
+
89
+ .tawcvs-swatches .swatch__tooltip {
90
+ -webkit-transform: translate(-50%, -100%);
91
+ -moz-transform: translate(-50%, -100%);
92
+ transform: translate(-50%, -100%);
93
+ -webkit-transition: all 0.3s;
94
+ -moz-transition: all 0.3s;
95
+ -ms-transition: all 0.3s;
96
+ -o-transition: all 0.3s;
97
+ transition: all 0.3s;
98
+ -webkit-border-radius: 3px;
99
+ -moz-border-radius: 3px;
100
+ border-radius: 3px;
101
+ position: absolute;
102
+ left: 50%;
103
+ top: 0;
104
+ background: #333;
105
+ z-index: 2;
106
+ color: #fff;
107
+ margin: -15px 0 0 0;
108
+ padding: 5px 10px;
109
+ text-indent: initial;
110
+ font-size: 14px;
111
+ font-weight: 500;
112
+ opacity: 0;
113
+ visibility: hidden;
114
+ user-select: none;
115
+ }
116
+
117
+ .tawcvs-swatches .swatch__tooltip:after {
118
+ -webkit-transform: rotate(45deg);
119
+ -moz-transform: rotate(45deg);
120
+ transform: rotate(45deg);
121
+ content: "";
122
+ position: absolute;
123
+ width: 12px;
124
+ height: 12px;
125
+ background: #333;
126
+ bottom: -4px;
127
+ left: 50%;
128
+ margin-left: -6px;
129
+ }
130
+ .tawcvs-swatches .swatch:hover .swatch__tooltip {
131
+ opacity: 1;
132
+ visibility: visible;
133
+ user-select: auto;
134
+ }
assets/js/admin.js CHANGED
@@ -1,143 +1,143 @@
1
- var frame,
2
- tawcvs = tawcvs || {};
3
-
4
- jQuery( document ).ready( function ( $ ) {
5
- 'use strict';
6
- var wp = window.wp,
7
- $body = $( 'body' );
8
-
9
- $( '#term-color' ).wpColorPicker();
10
-
11
- // Update attribute image
12
- $body.on( 'click', '.tawcvs-upload-image-button', function ( event ) {
13
- event.preventDefault();
14
-
15
- var $button = $( this );
16
-
17
- // If the media frame already exists, reopen it.
18
- if ( frame ) {
19
- frame.open();
20
- return;
21
- }
22
-
23
- // Create the media frame.
24
- frame = wp.media.frames.downloadable_file = wp.media( {
25
- title : tawcvs.i18n.mediaTitle,
26
- button : {
27
- text: tawcvs.i18n.mediaButton
28
- },
29
- multiple: false
30
- } );
31
-
32
- // When an image is selected, run a callback.
33
- frame.on( 'select', function () {
34
- var attachment = frame.state().get( 'selection' ).first().toJSON();
35
-
36
- $button.siblings( 'input.tawcvs-term-image' ).val( attachment.id );
37
- $button.siblings( '.tawcvs-remove-image-button' ).show();
38
- $button.parent().prev( '.tawcvs-term-image-thumbnail' ).find( 'img' ).attr( 'src', attachment.sizes.thumbnail.url );
39
- } );
40
-
41
- // Finally, open the modal.
42
- frame.open();
43
-
44
- } ).on( 'click', '.tawcvs-remove-image-button', function () {
45
- var $button = $( this );
46
-
47
- $button.siblings( 'input.tawcvs-term-image' ).val( '' );
48
- $button.siblings( '.tawcvs-remove-image-button' ).show();
49
- $button.parent().prev( '.tawcvs-term-image-thumbnail' ).find( 'img' ).attr( 'src', tawcvs.placeholder );
50
-
51
- return false;
52
- } );
53
-
54
- // Toggle add new attribute term modal
55
- var $modal = $( '#tawcvs-modal-container' ),
56
- $spinner = $modal.find( '.spinner' ),
57
- $msg = $modal.find( '.message' ),
58
- $metabox = null;
59
-
60
- $body.on( 'click', '.tawcvs_add_new_attribute', function ( e ) {
61
- e.preventDefault();
62
- var $button = $( this ),
63
- taxInputTemplate = wp.template( 'tawcvs-input-tax' ),
64
- data = {
65
- type: $button.data( 'type' ),
66
- tax : $button.closest( '.woocommerce_attribute' ).data( 'taxonomy' )
67
- };
68
-
69
- // Insert input
70
- $modal.find( '.tawcvs-term-swatch' ).html( $( '#tmpl-tawcvs-input-' + data.type ).html() );
71
- $modal.find( '.tawcvs-term-tax' ).html( taxInputTemplate( data ) );
72
-
73
- if ( 'color' == data.type ) {
74
- $modal.find( 'input.tawcvs-input-color' ).wpColorPicker();
75
- }
76
-
77
- $metabox = $button.closest( '.woocommerce_attribute.wc-metabox' );
78
- $modal.show();
79
- } ).on( 'click', '.tawcvs-modal-close, .tawcvs-modal-backdrop', function ( e ) {
80
- e.preventDefault();
81
-
82
- closeModal();
83
- } );
84
-
85
- // Send ajax request to add new attribute term
86
- $body.on( 'click', '.tawcvs-new-attribute-submit', function ( e ) {
87
- e.preventDefault();
88
-
89
- var $button = $( this ),
90
- type = $button.data( 'type' ),
91
- error = false,
92
- data = {};
93
-
94
- // Validate
95
- $modal.find( '.tawcvs-input' ).each( function () {
96
- var $this = $( this );
97
-
98
- if ( $this.attr( 'name' ) != 'slug' && !$this.val() ) {
99
- $this.addClass( 'error' );
100
- error = true;
101
- } else {
102
- $this.removeClass( 'error' );
103
- }
104
-
105
- data[$this.attr( 'name' )] = $this.val();
106
- } );
107
-
108
- if ( error ) {
109
- return;
110
- }
111
-
112
- // Send ajax request
113
- $spinner.addClass( 'is-active' );
114
- $msg.hide();
115
- wp.ajax.send( 'tawcvs_add_new_attribute', {
116
- data : data,
117
- error : function ( res ) {
118
- $spinner.removeClass( 'is-active' );
119
- $msg.addClass( 'error' ).text( res ).show();
120
- },
121
- success: function ( res ) {
122
- $spinner.removeClass( 'is-active' );
123
- $msg.addClass( 'success' ).text( res.msg ).show();
124
-
125
- $metabox.find( 'select.attribute_values' ).append( '<option value="' + res.id + '" selected="selected">' + res.name + '</option>' );
126
- $metabox.find( 'select.attribute_values' ).change();
127
-
128
- closeModal();
129
- }
130
- } );
131
- } );
132
-
133
- /**
134
- * Close modal
135
- */
136
- function closeModal() {
137
- $modal.find( '.tawcvs-term-name input, .tawcvs-term-slug input' ).val( '' );
138
- $spinner.removeClass( 'is-active' );
139
- $msg.removeClass( 'error success' ).hide();
140
- $modal.hide();
141
- }
142
- } );
143
-
1
+ var frame,
2
+ tawcvs = tawcvs || {};
3
+
4
+ jQuery( document ).ready( function ( $ ) {
5
+ 'use strict';
6
+ var wp = window.wp,
7
+ $body = $( 'body' );
8
+
9
+ $( '#term-color' ).wpColorPicker();
10
+
11
+ // Update attribute image
12
+ $body.on( 'click', '.tawcvs-upload-image-button', function ( event ) {
13
+ event.preventDefault();
14
+
15
+ var $button = $( this );
16
+
17
+ // If the media frame already exists, reopen it.
18
+ if ( frame ) {
19
+ frame.open();
20
+ return;
21
+ }
22
+
23
+ // Create the media frame.
24
+ frame = wp.media.frames.downloadable_file = wp.media( {
25
+ title : tawcvs.i18n.mediaTitle,
26
+ button : {
27
+ text: tawcvs.i18n.mediaButton
28
+ },
29
+ multiple: false
30
+ } );
31
+
32
+ // When an image is selected, run a callback.
33
+ frame.on( 'select', function () {
34
+ var attachment = frame.state().get( 'selection' ).first().toJSON();
35
+
36
+ $button.siblings( 'input.tawcvs-term-image' ).val( attachment.id );
37
+ $button.siblings( '.tawcvs-remove-image-button' ).show();
38
+ $button.parent().prev( '.tawcvs-term-image-thumbnail' ).find( 'img' ).attr( 'src', attachment.sizes.thumbnail.url );
39
+ } );
40
+
41
+ // Finally, open the modal.
42
+ frame.open();
43
+
44
+ } ).on( 'click', '.tawcvs-remove-image-button', function () {
45
+ var $button = $( this );
46
+
47
+ $button.siblings( 'input.tawcvs-term-image' ).val( '' );
48
+ $button.siblings( '.tawcvs-remove-image-button' ).show();
49
+ $button.parent().prev( '.tawcvs-term-image-thumbnail' ).find( 'img' ).attr( 'src', tawcvs.placeholder );
50
+
51
+ return false;
52
+ } );
53
+
54
+ // Toggle add new attribute term modal
55
+ var $modal = $( '#tawcvs-modal-container' ),
56
+ $spinner = $modal.find( '.spinner' ),
57
+ $msg = $modal.find( '.message' ),
58
+ $metabox = null;
59
+
60
+ $body.on( 'click', '.tawcvs_add_new_attribute', function ( e ) {
61
+ e.preventDefault();
62
+ var $button = $( this ),
63
+ taxInputTemplate = wp.template( 'tawcvs-input-tax' ),
64
+ data = {
65
+ type: $button.data( 'type' ),
66
+ tax : $button.closest( '.woocommerce_attribute' ).data( 'taxonomy' )
67
+ };
68
+
69
+ // Insert input
70
+ $modal.find( '.tawcvs-term-swatch' ).html( $( '#tmpl-tawcvs-input-' + data.type ).html() );
71
+ $modal.find( '.tawcvs-term-tax' ).html( taxInputTemplate( data ) );
72
+
73
+ if ( 'color' == data.type ) {
74
+ $modal.find( 'input.tawcvs-input-color' ).wpColorPicker();
75
+ }
76
+
77
+ $metabox = $button.closest( '.woocommerce_attribute.wc-metabox' );
78
+ $modal.show();
79
+ } ).on( 'click', '.tawcvs-modal-close, .tawcvs-modal-backdrop', function ( e ) {
80
+ e.preventDefault();
81
+
82
+ closeModal();
83
+ } );
84
+
85
+ // Send ajax request to add new attribute term
86
+ $body.on( 'click', '.tawcvs-new-attribute-submit', function ( e ) {
87
+ e.preventDefault();
88
+
89
+ var $button = $( this ),
90
+ type = $button.data( 'type' ),
91
+ error = false,
92
+ data = {};
93
+
94
+ // Validate
95
+ $modal.find( '.tawcvs-input' ).each( function () {
96
+ var $this = $( this );
97
+
98
+ if ( $this.attr( 'name' ) != 'slug' && !$this.val() ) {
99
+ $this.addClass( 'error' );
100
+ error = true;
101
+ } else {
102
+ $this.removeClass( 'error' );
103
+ }
104
+
105
+ data[$this.attr( 'name' )] = $this.val();
106
+ } );
107
+
108
+ if ( error ) {
109
+ return;
110
+ }
111
+
112
+ // Send ajax request
113
+ $spinner.addClass( 'is-active' );
114
+ $msg.hide();
115
+ wp.ajax.send( 'tawcvs_add_new_attribute', {
116
+ data : data,
117
+ error : function ( res ) {
118
+ $spinner.removeClass( 'is-active' );
119
+ $msg.addClass( 'error' ).text( res ).show();
120
+ },
121
+ success: function ( res ) {
122
+ $spinner.removeClass( 'is-active' );
123
+ $msg.addClass( 'success' ).text( res.msg ).show();
124
+
125
+ $metabox.find( 'select.attribute_values' ).append( '<option value="' + res.id + '" selected="selected">' + res.name + '</option>' );
126
+ $metabox.find( 'select.attribute_values' ).change();
127
+
128
+ closeModal();
129
+ }
130
+ } );
131
+ } );
132
+
133
+ /**
134
+ * Close modal
135
+ */
136
+ function closeModal() {
137
+ $modal.find( '.tawcvs-term-name input, .tawcvs-term-slug input' ).val( '' );
138
+ $spinner.removeClass( 'is-active' );
139
+ $msg.removeClass( 'error success' ).hide();
140
+ $modal.hide();
141
+ }
142
+ } );
143
+
assets/js/frontend.js CHANGED
@@ -1,90 +1,90 @@
1
- ;(function ( $ ) {
2
- 'use strict';
3
-
4
- /**
5
- * @TODO Code a function that calculate available combination instead of use WC hooks
6
- */
7
- $.fn.tawcvs_variation_swatches_form = function () {
8
- return this.each( function() {
9
- var $form = $( this );
10
-
11
- $form
12
- .addClass( 'swatches-support' )
13
- .on( 'click', '.swatch', function ( e ) {
14
- e.preventDefault();
15
-
16
- var $el = $( this ),
17
- $select = $el.closest( '.value' ).find( 'select' ),
18
- value = $el.attr( 'data-value' );
19
-
20
- if ( $el.hasClass( 'disabled' ) ) {
21
- return;
22
- }
23
-
24
- // For old WC
25
- $select.trigger( 'focusin' );
26
-
27
- // Check if this combination is available
28
- if ( ! $select.find( 'option[value="' + value + '"]' ).length ) {
29
- $el.siblings( '.swatch' ).removeClass( 'selected' );
30
- $select.val( '' ).change();
31
- $form.trigger( 'tawcvs_no_matching_variations', [$el] );
32
- return;
33
- }
34
-
35
- if ( $el.hasClass( 'selected' ) ) {
36
- $select.val( '' );
37
- $el.removeClass( 'selected' );
38
- } else {
39
- $el.addClass( 'selected' ).siblings( '.selected' ).removeClass( 'selected' );
40
- $select.val( value );
41
- }
42
-
43
- $select.change();
44
- } )
45
- .on( 'click', '.reset_variations', function () {
46
- $form.find( '.swatch.selected' ).removeClass( 'selected' );
47
- $form.find( '.swatch.disabled' ).removeClass( 'disabled' );
48
- } )
49
- .on( 'woocommerce_update_variation_values', function() {
50
- setTimeout( function() {
51
- $form.find( 'tbody tr' ).each( function() {
52
- var $variationRow = $( this ),
53
- $options = $variationRow.find( 'select' ).find( 'option' ),
54
- $selected = $options.filter( ':selected' ),
55
- values = [];
56
-
57
- $options.each( function( index, option ) {
58
- if ( option.value !== '' ) {
59
- values.push( option.value );
60
- }
61
- } );
62
-
63
- $variationRow.find( '.swatch' ).each( function() {
64
- var $swatch = $( this ),
65
- value = $swatch.attr( 'data-value' );
66
-
67
- if ( values.indexOf( value ) > -1 ) {
68
- $swatch.removeClass( 'disabled' );
69
- } else {
70
- $swatch.addClass( 'disabled' );
71
-
72
- if ( $selected.length && value === $selected.val() ) {
73
- $swatch.removeClass( 'selected' );
74
- }
75
- }
76
- } );
77
- } );
78
- }, 100 );
79
- } )
80
- .on( 'tawcvs_no_matching_variations', function() {
81
- window.alert( wc_add_to_cart_variation_params.i18n_no_matching_variations_text );
82
- } );
83
- } );
84
- };
85
-
86
- $( function () {
87
- $( '.variations_form' ).tawcvs_variation_swatches_form();
88
- $( document.body ).trigger( 'tawcvs_initialized' );
89
- } );
90
- })( jQuery );
1
+ ;(function ( $ ) {
2
+ 'use strict';
3
+
4
+ /**
5
+ * @TODO Code a function that calculate available combination instead of use WC hooks
6
+ */
7
+ $.fn.tawcvs_variation_swatches_form = function () {
8
+ return this.each( function() {
9
+ var $form = $( this );
10
+
11
+ $form
12
+ .addClass( 'swatches-support' )
13
+ .on( 'click', '.swatch', function ( e ) {
14
+ e.preventDefault();
15
+
16
+ var $el = $( this ),
17
+ $select = $el.closest( '.value' ).find( 'select' ),
18
+ value = $el.attr( 'data-value' );
19
+
20
+ if ( $el.hasClass( 'disabled' ) ) {
21
+ return;
22
+ }
23
+
24
+ // For old WC
25
+ $select.trigger( 'focusin' );
26
+
27
+ // Check if this combination is available
28
+ if ( ! $select.find( 'option[value="' + value + '"]' ).length ) {
29
+ $el.siblings( '.swatch' ).removeClass( 'selected' );
30
+ $select.val( '' ).change();
31
+ $form.trigger( 'tawcvs_no_matching_variations', [$el] );
32
+ return;
33
+ }
34
+
35
+ if ( $el.hasClass( 'selected' ) ) {
36
+ $select.val( '' );
37
+ $el.removeClass( 'selected' );
38
+ } else {
39
+ $el.addClass( 'selected' ).siblings( '.selected' ).removeClass( 'selected' );
40
+ $select.val( value );
41
+ }
42
+
43
+ $select.change();
44
+ } )
45
+ .on( 'click', '.reset_variations', function () {
46
+ $form.find( '.swatch.selected' ).removeClass( 'selected' );
47
+ $form.find( '.swatch.disabled' ).removeClass( 'disabled' );
48
+ } )
49
+ .on( 'woocommerce_update_variation_values', function() {
50
+ setTimeout( function() {
51
+ $form.find( 'tbody tr' ).each( function() {
52
+ var $variationRow = $( this ),
53
+ $options = $variationRow.find( 'select' ).find( 'option' ),
54
+ $selected = $options.filter( ':selected' ),
55
+ values = [];
56
+
57
+ $options.each( function( index, option ) {
58
+ if ( option.value !== '' ) {
59
+ values.push( option.value );
60
+ }
61
+ } );
62
+
63
+ $variationRow.find( '.swatch' ).each( function() {
64
+ var $swatch = $( this ),
65
+ value = $swatch.attr( 'data-value' );
66
+
67
+ if ( values.indexOf( value ) > -1 ) {
68
+ $swatch.removeClass( 'disabled' );
69
+ } else {
70
+ $swatch.addClass( 'disabled' );
71
+
72
+ if ( $selected.length && value === $selected.val() ) {
73
+ $swatch.removeClass( 'selected' );
74
+ }
75
+ }
76
+ } );
77
+ } );
78
+ }, 100 );
79
+ } )
80
+ .on( 'tawcvs_no_matching_variations', function() {
81
+ window.alert( wc_add_to_cart_variation_params.i18n_no_matching_variations_text );
82
+ } );
83
+ } );
84
+ };
85
+
86
+ $( function () {
87
+ $( '.variations_form' ).tawcvs_variation_swatches_form();
88
+ $( document.body ).trigger( 'tawcvs_initialized' );
89
+ } );
90
+ })( jQuery );
includes/class-admin-product.php CHANGED
@@ -1,184 +1,184 @@
1
- <?php
2
-
3
- /**
4
- * Class TA_WC_Variation_Swatches_Admin_Product
5
- */
6
- class TA_WC_Variation_Swatches_Admin_Product {
7
- /**
8
- * Class constructor.
9
- */
10
- public function __construct() {
11
- add_action( 'woocommerce_product_option_terms', array( $this, 'product_option_terms' ), 10, 2 );
12
-
13
- add_action( 'wp_ajax_tawcvs_add_new_attribute', array( $this, 'add_new_attribute_ajax' ) );
14
- add_action( 'admin_footer', array( $this, 'add_attribute_term_template' ) );
15
- }
16
-
17
- /**
18
- * Add selector for extra attribute types
19
- *
20
- * @param $taxonomy
21
- * @param $index
22
- */
23
- public function product_option_terms( $taxonomy, $index ) {
24
- if ( ! array_key_exists( $taxonomy->attribute_type, TA_WCVS()->types ) ) {
25
- return;
26
- }
27
-
28
- $taxonomy_name = wc_attribute_taxonomy_name( $taxonomy->attribute_name );
29
- global $thepostid;
30
-
31
- $product_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $thepostid;
32
- ?>
33
-
34
- <select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'wcvs' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo $index; ?>][]">
35
- <?php
36
-
37
- $all_terms = get_terms( $taxonomy_name, apply_filters( 'woocommerce_product_attribute_terms', array( 'orderby' => 'name', 'hide_empty' => false ) ) );
38
- if ( $all_terms ) {
39
- foreach ( $all_terms as $term ) {
40
- echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( has_term( absint( $term->term_id ), $taxonomy_name, $product_id ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
41
- }
42
- }
43
- ?>
44
- </select>
45
- <button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'wcvs' ); ?></button>
46
- <button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'wcvs' ); ?></button>
47
- <button class="button fr plus tawcvs_add_new_attribute" data-type="<?php echo $taxonomy->attribute_type ?>"><?php esc_html_e( 'Add new', 'wcvs' ); ?></button>
48
-
49
- <?php
50
- }
51
-
52
- /**
53
- * Ajax function handles adding new attribute term
54
- */
55
- public function add_new_attribute_ajax() {
56
- $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
57
- $tax = isset( $_POST['taxonomy'] ) ? sanitize_text_field( $_POST['taxonomy'] ) : '';
58
- $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : '';
59
- $name = isset( $_POST['name'] ) ? sanitize_text_field( $_POST['name'] ) : '';
60
- $slug = isset( $_POST['slug'] ) ? sanitize_text_field( $_POST['slug'] ) : '';
61
- $swatch = isset( $_POST['swatch'] ) ? sanitize_text_field( $_POST['swatch'] ) : '';
62
-
63
- if ( ! wp_verify_nonce( $nonce, '_tawcvs_create_attribute' ) ) {
64
- wp_send_json_error( esc_html__( 'Wrong request', 'wcvs' ) );
65
- }
66
-
67
- if ( empty( $name ) || empty( $swatch ) || empty( $tax ) || empty( $type ) ) {
68
- wp_send_json_error( esc_html__( 'Not enough data', 'wcvs' ) );
69
- }
70
-
71
- if ( ! taxonomy_exists( $tax ) ) {
72
- wp_send_json_error( esc_html__( 'Taxonomy is not exists', 'wcvs' ) );
73
- }
74
-
75
- if ( term_exists( $_POST['name'], $_POST['tax'] ) ) {
76
- wp_send_json_error( esc_html__( 'This term is exists', 'wcvs' ) );
77
- }
78
-
79
- $term = wp_insert_term( $name, $tax, array( 'slug' => $slug ) );
80
-
81
- if ( is_wp_error( $term ) ) {
82
- wp_send_json_error( $term->get_error_message() );
83
- } else {
84
- $term = get_term_by( 'id', $term['term_id'], $tax );
85
- update_term_meta( $term->term_id, $type, $swatch );
86
- }
87
-
88
- wp_send_json_success(
89
- array(
90
- 'msg' => esc_html__( 'Added successfully', 'wcvs' ),
91
- 'id' => $term->term_id,
92
- 'slug' => $term->slug,
93
- 'name' => $term->name,
94
- )
95
- );
96
- }
97
-
98
- /**
99
- * Print HTML of modal at admin footer and add js templates
100
- */
101
- public function add_attribute_term_template() {
102
- global $pagenow, $post;
103
-
104
- if ( $pagenow != 'post.php' || ( isset( $post ) && get_post_type( $post->ID ) != 'product' ) ) {
105
- return;
106
- }
107
- ?>
108
-
109
- <div id="tawcvs-modal-container" class="tawcvs-modal-container">
110
- <div class="tawcvs-modal">
111
- <button type="button" class="button-link media-modal-close tawcvs-modal-close">
112
- <span class="media-modal-icon"></span></button>
113
- <div class="tawcvs-modal-header"><h2><?php esc_html_e( 'Add new term', 'wcvs' ) ?></h2></div>
114
- <div class="tawcvs-modal-content">
115
- <p class="tawcvs-term-name">
116
- <label>
117
- <?php esc_html_e( 'Name', 'wcvs' ) ?>
118
- <input type="text" class="widefat tawcvs-input" name="name">
119
- </label>
120
- </p>
121
- <p class="tawcvs-term-slug">
122
- <label>
123
- <?php esc_html_e( 'Slug', 'wcvs' ) ?>
124
- <input type="text" class="widefat tawcvs-input" name="slug">
125
- </label>
126
- </p>
127
- <div class="tawcvs-term-swatch">
128
-
129
- </div>
130
- <div class="hidden tawcvs-term-tax"></div>
131
-
132
- <input type="hidden" class="tawcvs-input" name="nonce" value="<?php echo wp_create_nonce( '_tawcvs_create_attribute' ) ?>">
133
- </div>
134
- <div class="tawcvs-modal-footer">
135
- <button class="button button-secondary tawcvs-modal-close"><?php esc_html_e( 'Cancel', 'wcvs' ) ?></button>
136
- <button class="button button-primary tawcvs-new-attribute-submit"><?php esc_html_e( 'Add New', 'wcvs' ) ?></button>
137
- <span class="message"></span>
138
- <span class="spinner"></span>
139
- </div>
140
- </div>
141
- <div class="tawcvs-modal-backdrop media-modal-backdrop"></div>
142
- </div>
143
-
144
- <script type="text/template" id="tmpl-tawcvs-input-color">
145
-
146
- <label><?php esc_html_e( 'Color', 'wcvs' ) ?></label><br>
147
- <input type="text" class="tawcvs-input tawcvs-input-color" name="swatch">
148
-
149
- </script>
150
-
151
- <script type="text/template" id="tmpl-tawcvs-input-image">
152
-
153
- <label><?php esc_html_e( 'Image', 'wcvs' ) ?></label><br>
154
- <div class="tawcvs-term-image-thumbnail" style="float:left;margin-right:10px;">
155
- <img src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/placeholder.png' ) ?>" width="60px" height="60px" />
156
- </div>
157
- <div style="line-height:60px;">
158
- <input type="hidden" class="tawcvs-input tawcvs-input-image tawcvs-term-image" name="swatch" value="" />
159
- <button type="button" class="tawcvs-upload-image-button button"><?php esc_html_e( 'Upload/Add image', 'wcvs' ); ?></button>
160
- <button type="button" class="tawcvs-remove-image-button button hidden"><?php esc_html_e( 'Remove image', 'wcvs' ); ?></button>
161
- </div>
162
-
163
- </script>
164
-
165
- <script type="text/template" id="tmpl-tawcvs-input-label">
166
-
167
- <label>
168
- <?php esc_html_e( 'Label', 'wcvs' ) ?>
169
- <input type="text" class="widefat tawcvs-input tawcvs-input-label" name="swatch">
170
- </label>
171
-
172
- </script>
173
-
174
- <script type="text/template" id="tmpl-tawcvs-input-tax">
175
-
176
- <input type="hidden" class="tawcvs-input" name="taxonomy" value="{{data.tax}}">
177
- <input type="hidden" class="tawcvs-input" name="type" value="{{data.type}}">
178
-
179
- </script>
180
- <?php
181
- }
182
- }
183
-
184
  new TA_WC_Variation_Swatches_Admin_Product();
1
+ <?php
2
+
3
+ /**
4
+ * Class TA_WC_Variation_Swatches_Admin_Product
5
+ */
6
+ class TA_WC_Variation_Swatches_Admin_Product {
7
+ /**
8
+ * Class constructor.
9
+ */
10
+ public function __construct() {
11
+ add_action( 'woocommerce_product_option_terms', array( $this, 'product_option_terms' ), 10, 2 );
12
+
13
+ add_action( 'wp_ajax_tawcvs_add_new_attribute', array( $this, 'add_new_attribute_ajax' ) );
14
+ add_action( 'admin_footer', array( $this, 'add_attribute_term_template' ) );
15
+ }
16
+
17
+ /**
18
+ * Add selector for extra attribute types
19
+ *
20
+ * @param $taxonomy
21
+ * @param $index
22
+ */
23
+ public function product_option_terms( $taxonomy, $index ) {
24
+ if ( ! array_key_exists( $taxonomy->attribute_type, TA_WCVS()->types ) ) {
25
+ return;
26
+ }
27
+
28
+ $taxonomy_name = wc_attribute_taxonomy_name( $taxonomy->attribute_name );
29
+ global $thepostid;
30
+
31
+ $product_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $thepostid;
32
+ ?>
33
+
34
+ <select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'wcvs' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo $index; ?>][]">
35
+ <?php
36
+
37
+ $all_terms = get_terms( $taxonomy_name, apply_filters( 'woocommerce_product_attribute_terms', array( 'orderby' => 'name', 'hide_empty' => false ) ) );
38
+ if ( $all_terms ) {
39
+ foreach ( $all_terms as $term ) {
40
+ echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( has_term( absint( $term->term_id ), $taxonomy_name, $product_id ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
41
+ }
42
+ }
43
+ ?>
44
+ </select>
45
+ <button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'wcvs' ); ?></button>
46
+ <button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'wcvs' ); ?></button>
47
+ <button class="button fr plus tawcvs_add_new_attribute" data-type="<?php echo $taxonomy->attribute_type ?>"><?php esc_html_e( 'Add new', 'wcvs' ); ?></button>
48
+
49
+ <?php
50
+ }
51
+
52
+ /**
53
+ * Ajax function handles adding new attribute term
54
+ */
55
+ public function add_new_attribute_ajax() {
56
+ $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
57
+ $tax = isset( $_POST['taxonomy'] ) ? sanitize_text_field( $_POST['taxonomy'] ) : '';
58
+ $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : '';
59
+ $name = isset( $_POST['name'] ) ? sanitize_text_field( $_POST['name'] ) : '';
60
+ $slug = isset( $_POST['slug'] ) ? sanitize_text_field( $_POST['slug'] ) : '';
61
+ $swatch = isset( $_POST['swatch'] ) ? sanitize_text_field( $_POST['swatch'] ) : '';
62
+
63
+ if ( ! wp_verify_nonce( $nonce, '_tawcvs_create_attribute' ) ) {
64
+ wp_send_json_error( esc_html__( 'Wrong request', 'wcvs' ) );
65
+ }
66
+
67
+ if ( empty( $name ) || empty( $swatch ) || empty( $tax ) || empty( $type ) ) {
68
+ wp_send_json_error( esc_html__( 'Not enough data', 'wcvs' ) );
69
+ }
70
+
71
+ if ( ! taxonomy_exists( $tax ) ) {
72
+ wp_send_json_error( esc_html__( 'Taxonomy is not exists', 'wcvs' ) );
73
+ }
74
+
75
+ if ( term_exists( $_POST['name'], $_POST['tax'] ) ) {
76
+ wp_send_json_error( esc_html__( 'This term is exists', 'wcvs' ) );
77
+ }
78
+
79
+ $term = wp_insert_term( $name, $tax, array( 'slug' => $slug ) );
80
+
81
+ if ( is_wp_error( $term ) ) {
82
+ wp_send_json_error( $term->get_error_message() );
83
+ } else {
84
+ $term = get_term_by( 'id', $term['term_id'], $tax );
85
+ update_term_meta( $term->term_id, $type, $swatch );
86
+ }
87
+
88
+ wp_send_json_success(
89
+ array(
90
+ 'msg' => esc_html__( 'Added successfully', 'wcvs' ),
91
+ 'id' => $term->term_id,
92
+ 'slug' => $term->slug,
93
+ 'name' => $term->name,
94
+ )
95
+ );
96
+ }
97
+
98
+ /**
99
+ * Print HTML of modal at admin footer and add js templates
100
+ */
101
+ public function add_attribute_term_template() {
102
+ global $pagenow, $post;
103
+
104
+ if ( $pagenow != 'post.php' || ( isset( $post ) && get_post_type( $post->ID ) != 'product' ) ) {
105
+ return;
106
+ }
107
+ ?>
108
+
109
+ <div id="tawcvs-modal-container" class="tawcvs-modal-container">
110
+ <div class="tawcvs-modal">
111
+ <button type="button" class="button-link media-modal-close tawcvs-modal-close">
112
+ <span class="media-modal-icon"></span></button>
113
+ <div class="tawcvs-modal-header"><h2><?php esc_html_e( 'Add new term', 'wcvs' ) ?></h2></div>
114
+ <div class="tawcvs-modal-content">
115
+ <p class="tawcvs-term-name">
116
+ <label>
117
+ <?php esc_html_e( 'Name', 'wcvs' ) ?>
118
+ <input type="text" class="widefat tawcvs-input" name="name">
119
+ </label>
120
+ </p>
121
+ <p class="tawcvs-term-slug">
122
+ <label>
123
+ <?php esc_html_e( 'Slug', 'wcvs' ) ?>
124
+ <input type="text" class="widefat tawcvs-input" name="slug">
125
+ </label>
126
+ </p>
127
+ <div class="tawcvs-term-swatch">
128
+
129
+ </div>
130
+ <div class="hidden tawcvs-term-tax"></div>
131
+
132
+ <input type="hidden" class="tawcvs-input" name="nonce" value="<?php echo wp_create_nonce( '_tawcvs_create_attribute' ) ?>">
133
+ </div>
134
+ <div class="tawcvs-modal-footer">
135
+ <button class="button button-secondary tawcvs-modal-close"><?php esc_html_e( 'Cancel', 'wcvs' ) ?></button>
136
+ <button class="button button-primary tawcvs-new-attribute-submit"><?php esc_html_e( 'Add New', 'wcvs' ) ?></button>
137
+ <span class="message"></span>
138
+ <span class="spinner"></span>
139
+ </div>
140
+ </div>
141
+ <div class="tawcvs-modal-backdrop media-modal-backdrop"></div>
142
+ </div>
143
+
144
+ <script type="text/template" id="tmpl-tawcvs-input-color">
145
+
146
+ <label><?php esc_html_e( 'Color', 'wcvs' ) ?></label><br>
147
+ <input type="text" class="tawcvs-input tawcvs-input-color" name="swatch">
148
+
149
+ </script>
150
+
151
+ <script type="text/template" id="tmpl-tawcvs-input-image">
152
+
153
+ <label><?php esc_html_e( 'Image', 'wcvs' ) ?></label><br>
154
+ <div class="tawcvs-term-image-thumbnail" style="float:left;margin-right:10px;">
155
+ <img src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/placeholder.png' ) ?>" width="60px" height="60px" />
156
+ </div>
157
+ <div style="line-height:60px;">
158
+ <input type="hidden" class="tawcvs-input tawcvs-input-image tawcvs-term-image" name="swatch" value="" />
159
+ <button type="button" class="tawcvs-upload-image-button button"><?php esc_html_e( 'Upload/Add image', 'wcvs' ); ?></button>
160
+ <button type="button" class="tawcvs-remove-image-button button hidden"><?php esc_html_e( 'Remove image', 'wcvs' ); ?></button>
161
+ </div>
162
+
163
+ </script>
164
+
165
+ <script type="text/template" id="tmpl-tawcvs-input-label">
166
+
167
+ <label>
168
+ <?php esc_html_e( 'Label', 'wcvs' ) ?>
169
+ <input type="text" class="widefat tawcvs-input tawcvs-input-label" name="swatch">
170
+ </label>
171
+
172
+ </script>
173
+
174
+ <script type="text/template" id="tmpl-tawcvs-input-tax">
175
+
176
+ <input type="hidden" class="tawcvs-input" name="taxonomy" value="{{data.tax}}">
177
+ <input type="hidden" class="tawcvs-input" name="type" value="{{data.type}}">
178
+
179
+ </script>
180
+ <?php
181
+ }
182
+ }
183
+
184
  new TA_WC_Variation_Swatches_Admin_Product();
includes/class-admin.php CHANGED
@@ -1,313 +1,313 @@
1
- <?php
2
-
3
- /**
4
- * Class TA_WC_Variation_Swatches_Admin
5
- */
6
- class TA_WC_Variation_Swatches_Admin {
7
- /**
8
- * The single instance of the class
9
- *
10
- * @var TA_WC_Variation_Swatches_Admin
11
- */
12
- protected static $instance = null;
13
-
14
- /**
15
- * Main instance
16
- *
17
- * @return TA_WC_Variation_Swatches_Admin
18
- */
19
- public static function instance() {
20
- if ( null == self::$instance ) {
21
- self::$instance = new self();
22
- }
23
-
24
- return self::$instance;
25
- }
26
-
27
- /**
28
- * Class constructor.
29
- */
30
- public function __construct() {
31
- add_action( 'admin_init', array( $this, 'includes' ) );
32
- add_action( 'admin_init', array( $this, 'init_attribute_hooks' ) );
33
- add_action( 'admin_print_scripts', array( $this, 'enqueue_scripts' ) );
34
-
35
- // Restore attributes
36
- add_action( 'admin_notices', array( $this, 'restore_attributes_notice' ) );
37
- add_action( 'admin_init', array( $this, 'restore_attribute_types' ) );
38
-
39
- // Display attribute fields
40
- add_action( 'tawcvs_product_attribute_field', array( $this, 'attribute_fields' ), 10, 3 );
41
- }
42
-
43
- /**
44
- * Include any classes we need within admin.
45
- */
46
- public function includes() {
47
- include_once( dirname( __FILE__ ) . '/class-admin-product.php' );
48
- }
49
-
50
- /**
51
- * Init hooks for adding fields to attribute screen
52
- * Save new term meta
53
- * Add thumbnail column for attribute term
54
- */
55
- public function init_attribute_hooks() {
56
- $attribute_taxonomies = wc_get_attribute_taxonomies();
57
-
58
- if ( empty( $attribute_taxonomies ) ) {
59
- return;
60
- }
61
-
62
- foreach ( $attribute_taxonomies as $tax ) {
63
- add_action( 'pa_' . $tax->attribute_name . '_add_form_fields', array( $this, 'add_attribute_fields' ) );
64
- add_action( 'pa_' . $tax->attribute_name . '_edit_form_fields', array( $this, 'edit_attribute_fields' ), 10, 2 );
65
-
66
- add_filter( 'manage_edit-pa_' . $tax->attribute_name . '_columns', array( $this, 'add_attribute_columns' ) );
67
- add_filter( 'manage_pa_' . $tax->attribute_name . '_custom_column', array( $this, 'add_attribute_column_content' ), 10, 3 );
68
- }
69
-
70
- add_action( 'created_term', array( $this, 'save_term_meta' ), 10, 2 );
71
- add_action( 'edit_term', array( $this, 'save_term_meta' ), 10, 2 );
72
- }
73
-
74
- /**
75
- * Load stylesheet and scripts in edit product attribute screen
76
- */
77
- public function enqueue_scripts() {
78
- $screen = get_current_screen();
79
- if ( strpos( $screen->id, 'edit-pa_' ) === false && strpos( $screen->id, 'product' ) === false ) {
80
- return;
81
- }
82
-
83
- wp_enqueue_media();
84
-
85
- wp_enqueue_style( 'tawcvs-admin', plugins_url( '/assets/css/admin.css', dirname( __FILE__ ) ), array( 'wp-color-picker' ), '20160615' );
86
- wp_enqueue_script( 'tawcvs-admin', plugins_url( '/assets/js/admin.js', dirname( __FILE__ ) ), array( 'jquery', 'wp-color-picker', 'wp-util' ), '20170113', true );
87
-
88
- wp_localize_script(
89
- 'tawcvs-admin',
90
- 'tawcvs',
91
- array(
92
- 'i18n' => array(
93
- 'mediaTitle' => esc_html__( 'Choose an image', 'wcvs' ),
94
- 'mediaButton' => esc_html__( 'Use image', 'wcvs' ),
95
- ),
96
- 'placeholder' => WC()->plugin_url() . '/assets/images/placeholder.png'
97
- )
98
- );
99
- }
100
-
101
- /**
102
- * Display a notice of restoring attribute types
103
- */
104
- public function restore_attributes_notice() {
105
- if ( get_transient( 'tawcvs_attribute_taxonomies' ) && ! get_option( 'tawcvs_restore_attributes_time' ) ) {
106
- ?>
107
- <div class="notice-warning notice is-dismissible">
108
- <p>
109
- <?php
110
- esc_html_e( 'Found a backup of product attributes types. This backup was generated at', 'wcvs' );
111
- echo ' ' . date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), get_option( 'tawcvs_backup_attributes_time' ) ) . '.';
112
- ?>
113
- </p>
114
- <p>
115
- <a href="<?php echo esc_url( add_query_arg( array( 'tawcvs_action' => 'restore_attributes_types', 'tawcvs_nonce' => wp_create_nonce( 'restore_attributes_types' ) ) ) ); ?>">
116
- <strong><?php esc_html_e( 'Restore product attributes types', 'wcvs' ); ?></strong>
117
- </a>
118
- |
119
- <a href="<?php echo esc_url( add_query_arg( array( 'tawcvs_action' => 'dismiss_restore_notice', 'tawcvs_nonce' => wp_create_nonce( 'dismiss_restore_notice' ) ) ) ); ?>">
120
- <strong><?php esc_html_e( 'Dismiss this notice', 'wcvs' ); ?></strong>
121
- </a>
122
- </p>
123
- </div>
124
- <?php
125
- } elseif ( isset( $_GET['tawcvs_message'] ) && 'restored' == $_GET['tawcvs_message'] ) {
126
- ?>
127
- <div class="notice-warning settings-error notice is-dismissible">
128
- <p><?php esc_html_e( 'All attributes types have been restored.', 'wcvs' ) ?></p>
129
- </div>
130
- <?php
131
- }
132
- }
133
-
134
- /**
135
- * Restore attribute types
136
- */
137
- public function restore_attribute_types() {
138
- if ( ! isset( $_GET['tawcvs_action'] ) || ! isset( $_GET['tawcvs_nonce'] ) ) {
139
- return;
140
- }
141
-
142
- if ( ! wp_verify_nonce( $_GET['tawcvs_nonce'], $_GET['tawcvs_action'] ) ) {
143
- return;
144
- }
145
-
146
- if ( 'restore_attributes_types' == $_GET['tawcvs_action'] ) {
147
- global $wpdb;
148
-
149
- $attribute_taxnomies = get_transient( 'tawcvs_attribute_taxonomies' );
150
-
151
- foreach ( $attribute_taxnomies as $id => $attribute ) {
152
- $wpdb->update(
153
- $wpdb->prefix . 'woocommerce_attribute_taxonomies',
154
- array( 'attribute_type' => $attribute->attribute_type ),
155
- array( 'attribute_id' => $id ),
156
- array( '%s' ),
157
- array( '%d' )
158
- );
159
- }
160
-
161
- update_option( 'tawcvs_restore_attributes_time', time() );
162
- delete_transient( 'tawcvs_attribute_taxonomies' );
163
- delete_transient( 'wc_attribute_taxonomies' );
164
-
165
- $url = remove_query_arg( array( 'tawcvs_action', 'tawcvs_nonce' ) );
166
- $url = add_query_arg( array( 'tawcvs_message' => 'restored' ), $url );
167
- } elseif ( 'dismiss_restore_notice' == $_GET['tawcvs_action'] ) {
168
- update_option( 'tawcvs_restore_attributes_time', 'ignored' );
169
- $url = remove_query_arg( array( 'tawcvs_action', 'tawcvs_nonce' ) );
170
- }
171
-
172
- if ( isset( $url ) ) {
173
- wp_redirect( $url );
174
- exit;
175
- }
176
- }
177
-
178
- /**
179
- * Create hook to add fields to add attribute term screen
180
- *
181
- * @param string $taxonomy
182
- */
183
- public function add_attribute_fields( $taxonomy ) {
184
- $attr = TA_WCVS()->get_tax_attribute( $taxonomy );
185
-
186
- do_action( 'tawcvs_product_attribute_field', $attr->attribute_type, '', 'add' );
187
- }
188
-
189
- /**
190
- * Create hook to fields to edit attribute term screen
191
- *
192
- * @param object $term
193
- * @param string $taxonomy
194
- */
195
- public function edit_attribute_fields( $term, $taxonomy ) {
196
- $attr = TA_WCVS()->get_tax_attribute( $taxonomy );
197
- $value = get_term_meta( $term->term_id, $attr->attribute_type, true );
198
-
199
- do_action( 'tawcvs_product_attribute_field', $attr->attribute_type, $value, 'edit' );
200
- }
201
-
202
- /**
203
- * Print HTML of custom fields on attribute term screens
204
- *
205
- * @param $type
206
- * @param $value
207
- * @param $form
208
- */
209
- public function attribute_fields( $type, $value, $form ) {
210
- // Return if this is a default attribute type
211
- if ( in_array( $type, array( 'select', 'text' ) ) ) {
212
- return;
213
- }
214
-
215
- // Print the open tag of field container
216
- printf(
217
- '<%s class="form-field">%s<label for="term-%s">%s</label>%s',
218
- 'edit' == $form ? 'tr' : 'div',
219
- 'edit' == $form ? '<th>' : '',
220
- esc_attr( $type ),
221
- TA_WCVS()->types[$type],
222
- 'edit' == $form ? '</th><td>' : ''
223
- );
224
-
225
- switch ( $type ) {
226
- case 'image':
227
- $image = $value ? wp_get_attachment_image_src( $value ) : '';
228
- $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
229
- ?>
230
- <div class="tawcvs-term-image-thumbnail" style="float:left;margin-right:10px;">
231
- <img src="<?php echo esc_url( $image ) ?>" width="60px" height="60px" />
232
- </div>
233
- <div style="line-height:60px;">
234
- <input type="hidden" class="tawcvs-term-image" name="image" value="<?php echo esc_attr( $value ) ?>" />
235
- <button type="button" class="tawcvs-upload-image-button button"><?php esc_html_e( 'Upload/Add image', 'wcvs' ); ?></button>
236
- <button type="button" class="tawcvs-remove-image-button button <?php echo $value ? '' : 'hidden' ?>"><?php esc_html_e( 'Remove image', 'wcvs' ); ?></button>
237
- </div>
238
- <?php
239
- break;
240
-
241
- default:
242
- ?>
243
- <input type="text" id="term-<?php echo esc_attr( $type ) ?>" name="<?php echo esc_attr( $type ) ?>" value="<?php echo esc_attr( $value ) ?>" />
244
- <?php
245
- break;
246
- }
247
-
248
- // Print the close tag of field container
249
- echo 'edit' == $form ? '</td></tr>' : '</div>';
250
- }
251
-
252
- /**
253
- * Save term meta
254
- *
255
- * @param int $term_id
256
- * @param int $tt_id
257
- */
258
- public function save_term_meta( $term_id, $tt_id ) {
259
- foreach ( TA_WCVS()->types as $type => $label ) {
260
- if ( isset( $_POST[$type] ) ) {
261
- update_term_meta( $term_id, $type, sanitize_text_field( $_POST[$type] ) );
262
- }
263
- }
264
- }
265
-
266
- /**
267
- * Add thumbnail column to column list
268
- *
269
- * @param array $columns
270
- *
271
- * @return array
272
- */
273
- public function add_attribute_columns( $columns ) {
274
- $new_columns = array();
275
- $new_columns['cb'] = $columns['cb'];
276
- $new_columns['thumb'] = '';
277
- unset( $columns['cb'] );
278
-
279
- return array_merge( $new_columns, $columns );
280
- }
281
-
282
- /**
283
- * Render thumbnail HTML depend on attribute type
284
- *
285
- * @param $columns
286
- * @param $column
287
- * @param $term_id
288
- */
289
- public function add_attribute_column_content( $columns, $column, $term_id ) {
290
- if ( 'thumb' !== $column ) {
291
- return $columns;
292
- }
293
-
294
- $attr = TA_WCVS()->get_tax_attribute( $_REQUEST['taxonomy'] );
295
- $value = get_term_meta( $term_id, $attr->attribute_type, true );
296
-
297
- switch ( $attr->attribute_type ) {
298
- case 'color':
299
- printf( '<div class="swatch-preview swatch-color" style="background-color:%s;"></div>', esc_attr( $value ) );
300
- break;
301
-
302
- case 'image':
303
- $image = $value ? wp_get_attachment_image_src( $value ) : '';
304
- $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
305
- printf( '<img class="swatch-preview swatch-image" src="%s" width="44px" height="44px">', esc_url( $image ) );
306
- break;
307
-
308
- case 'label':
309
- printf( '<div class="swatch-preview swatch-label">%s</div>', esc_html( $value ) );
310
- break;
311
- }
312
- }
313
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class TA_WC_Variation_Swatches_Admin
5
+ */
6
+ class TA_WC_Variation_Swatches_Admin {
7
+ /**
8
+ * The single instance of the class
9
+ *
10
+ * @var TA_WC_Variation_Swatches_Admin
11
+ */
12
+ protected static $instance = null;
13
+
14
+ /**
15
+ * Main instance
16
+ *
17
+ * @return TA_WC_Variation_Swatches_Admin
18
+ */
19
+ public static function instance() {
20
+ if ( null == self::$instance ) {
21
+ self::$instance = new self();
22
+ }
23
+
24
+ return self::$instance;
25
+ }
26
+
27
+ /**
28
+ * Class constructor.
29
+ */
30
+ public function __construct() {
31
+ add_action( 'admin_init', array( $this, 'includes' ) );
32
+ add_action( 'admin_init', array( $this, 'init_attribute_hooks' ) );
33
+ add_action( 'admin_print_scripts', array( $this, 'enqueue_scripts' ) );
34
+
35
+ // Restore attributes
36
+ add_action( 'admin_notices', array( $this, 'restore_attributes_notice' ) );
37
+ add_action( 'admin_init', array( $this, 'restore_attribute_types' ) );
38
+
39
+ // Display attribute fields
40
+ add_action( 'tawcvs_product_attribute_field', array( $this, 'attribute_fields' ), 10, 3 );
41
+ }
42
+
43
+ /**
44
+ * Include any classes we need within admin.
45
+ */
46
+ public function includes() {
47
+ include_once( dirname( __FILE__ ) . '/class-admin-product.php' );
48
+ }
49
+
50
+ /**
51
+ * Init hooks for adding fields to attribute screen
52
+ * Save new term meta
53
+ * Add thumbnail column for attribute term
54
+ */
55
+ public function init_attribute_hooks() {
56
+ $attribute_taxonomies = wc_get_attribute_taxonomies();
57
+
58
+ if ( empty( $attribute_taxonomies ) ) {
59
+ return;
60
+ }
61
+
62
+ foreach ( $attribute_taxonomies as $tax ) {
63
+ add_action( 'pa_' . $tax->attribute_name . '_add_form_fields', array( $this, 'add_attribute_fields' ) );
64
+ add_action( 'pa_' . $tax->attribute_name . '_edit_form_fields', array( $this, 'edit_attribute_fields' ), 10, 2 );
65
+
66
+ add_filter( 'manage_edit-pa_' . $tax->attribute_name . '_columns', array( $this, 'add_attribute_columns' ) );
67
+ add_filter( 'manage_pa_' . $tax->attribute_name . '_custom_column', array( $this, 'add_attribute_column_content' ), 10, 3 );
68
+ }
69
+
70
+ add_action( 'created_term', array( $this, 'save_term_meta' ), 10, 2 );
71
+ add_action( 'edit_term', array( $this, 'save_term_meta' ), 10, 2 );
72
+ }
73
+
74
+ /**
75
+ * Load stylesheet and scripts in edit product attribute screen
76
+ */
77
+ public function enqueue_scripts() {
78
+ $screen = get_current_screen();
79
+ if ( strpos( $screen->id, 'edit-pa_' ) === false && strpos( $screen->id, 'product' ) === false ) {
80
+ return;
81
+ }
82
+
83
+ wp_enqueue_media();
84
+
85
+ wp_enqueue_style( 'tawcvs-admin', plugins_url( '/assets/css/admin.css', dirname( __FILE__ ) ), array( 'wp-color-picker' ), '20160615' );
86
+ wp_enqueue_script( 'tawcvs-admin', plugins_url( '/assets/js/admin.js', dirname( __FILE__ ) ), array( 'jquery', 'wp-color-picker', 'wp-util' ), '20170113', true );
87
+
88
+ wp_localize_script(
89
+ 'tawcvs-admin',
90
+ 'tawcvs',
91
+ array(
92
+ 'i18n' => array(
93
+ 'mediaTitle' => esc_html__( 'Choose an image', 'wcvs' ),
94
+ 'mediaButton' => esc_html__( 'Use image', 'wcvs' ),
95
+ ),
96
+ 'placeholder' => WC()->plugin_url() . '/assets/images/placeholder.png'
97
+ )
98
+ );
99
+ }
100
+
101
+ /**
102
+ * Display a notice of restoring attribute types
103
+ */
104
+ public function restore_attributes_notice() {
105
+ if ( get_transient( 'tawcvs_attribute_taxonomies' ) && ! get_option( 'tawcvs_restore_attributes_time' ) ) {
106
+ ?>
107
+ <div class="notice-warning notice is-dismissible">
108
+ <p>
109
+ <?php
110
+ esc_html_e( 'Found a backup of product attributes types. This backup was generated at', 'wcvs' );
111
+ echo ' ' . date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), get_option( 'tawcvs_backup_attributes_time' ) ) . '.';
112
+ ?>
113
+ </p>
114
+ <p>
115
+ <a href="<?php echo esc_url( add_query_arg( array( 'tawcvs_action' => 'restore_attributes_types', 'tawcvs_nonce' => wp_create_nonce( 'restore_attributes_types' ) ) ) ); ?>">
116
+ <strong><?php esc_html_e( 'Restore product attributes types', 'wcvs' ); ?></strong>
117
+ </a>
118
+ |
119
+ <a href="<?php echo esc_url( add_query_arg( array( 'tawcvs_action' => 'dismiss_restore_notice', 'tawcvs_nonce' => wp_create_nonce( 'dismiss_restore_notice' ) ) ) ); ?>">
120
+ <strong><?php esc_html_e( 'Dismiss this notice', 'wcvs' ); ?></strong>
121
+ </a>
122
+ </p>
123
+ </div>
124
+ <?php
125
+ } elseif ( isset( $_GET['tawcvs_message'] ) && 'restored' == $_GET['tawcvs_message'] ) {
126
+ ?>
127
+ <div class="notice-warning settings-error notice is-dismissible">
128
+ <p><?php esc_html_e( 'All attributes types have been restored.', 'wcvs' ) ?></p>
129
+ </div>
130
+ <?php
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Restore attribute types
136
+ */
137
+ public function restore_attribute_types() {
138
+ if ( ! isset( $_GET['tawcvs_action'] ) || ! isset( $_GET['tawcvs_nonce'] ) ) {
139
+ return;
140
+ }
141
+
142
+ if ( ! wp_verify_nonce( $_GET['tawcvs_nonce'], $_GET['tawcvs_action'] ) ) {
143
+ return;
144
+ }
145
+
146
+ if ( 'restore_attributes_types' == $_GET['tawcvs_action'] ) {
147
+ global $wpdb;
148
+
149
+ $attribute_taxnomies = get_transient( 'tawcvs_attribute_taxonomies' );
150
+
151
+ foreach ( $attribute_taxnomies as $id => $attribute ) {
152
+ $wpdb->update(
153
+ $wpdb->prefix . 'woocommerce_attribute_taxonomies',
154
+ array( 'attribute_type' => $attribute->attribute_type ),
155
+ array( 'attribute_id' => $id ),
156
+ array( '%s' ),
157
+ array( '%d' )
158
+ );
159
+ }
160
+
161
+ update_option( 'tawcvs_restore_attributes_time', time() );
162
+ delete_transient( 'tawcvs_attribute_taxonomies' );
163
+ delete_transient( 'wc_attribute_taxonomies' );
164
+
165
+ $url = remove_query_arg( array( 'tawcvs_action', 'tawcvs_nonce' ) );
166
+ $url = add_query_arg( array( 'tawcvs_message' => 'restored' ), $url );
167
+ } elseif ( 'dismiss_restore_notice' == $_GET['tawcvs_action'] ) {
168
+ update_option( 'tawcvs_restore_attributes_time', 'ignored' );
169
+ $url = remove_query_arg( array( 'tawcvs_action', 'tawcvs_nonce' ) );
170
+ }
171
+
172
+ if ( isset( $url ) ) {
173
+ wp_redirect( $url );
174
+ exit;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Create hook to add fields to add attribute term screen
180
+ *
181
+ * @param string $taxonomy
182
+ */
183
+ public function add_attribute_fields( $taxonomy ) {
184
+ $attr = TA_WCVS()->get_tax_attribute( $taxonomy );
185
+
186
+ do_action( 'tawcvs_product_attribute_field', $attr->attribute_type, '', 'add' );
187
+ }
188
+
189
+ /**
190
+ * Create hook to fields to edit attribute term screen
191
+ *
192
+ * @param object $term
193
+ * @param string $taxonomy
194
+ */
195
+ public function edit_attribute_fields( $term, $taxonomy ) {
196
+ $attr = TA_WCVS()->get_tax_attribute( $taxonomy );
197
+ $value = get_term_meta( $term->term_id, $attr->attribute_type, true );
198
+
199
+ do_action( 'tawcvs_product_attribute_field', $attr->attribute_type, $value, 'edit' );
200
+ }
201
+
202
+ /**
203
+ * Print HTML of custom fields on attribute term screens
204
+ *
205
+ * @param $type
206
+ * @param $value
207
+ * @param $form
208
+ */
209
+ public function attribute_fields( $type, $value, $form ) {
210
+ // Return if this is a default attribute type
211
+ if ( in_array( $type, array( 'select', 'text' ) ) ) {
212
+ return;
213
+ }
214
+
215
+ // Print the open tag of field container
216
+ printf(
217
+ '<%s class="form-field">%s<label for="term-%s">%s</label>%s',
218
+ 'edit' == $form ? 'tr' : 'div',
219
+ 'edit' == $form ? '<th>' : '',
220
+ esc_attr( $type ),
221
+ TA_WCVS()->types[$type],
222
+ 'edit' == $form ? '</th><td>' : ''
223
+ );
224
+
225
+ switch ( $type ) {
226
+ case 'image':
227
+ $image = $value ? wp_get_attachment_image_src( $value ) : '';
228
+ $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
229
+ ?>
230
+ <div class="tawcvs-term-image-thumbnail" style="float:left;margin-right:10px;">
231
+ <img src="<?php echo esc_url( $image ) ?>" width="60px" height="60px" />
232
+ </div>
233
+ <div style="line-height:60px;">
234
+ <input type="hidden" class="tawcvs-term-image" name="image" value="<?php echo esc_attr( $value ) ?>" />
235
+ <button type="button" class="tawcvs-upload-image-button button"><?php esc_html_e( 'Upload/Add image', 'wcvs' ); ?></button>
236
+ <button type="button" class="tawcvs-remove-image-button button <?php echo $value ? '' : 'hidden' ?>"><?php esc_html_e( 'Remove image', 'wcvs' ); ?></button>
237
+ </div>
238
+ <?php
239
+ break;
240
+
241
+ default:
242
+ ?>
243
+ <input type="text" id="term-<?php echo esc_attr( $type ) ?>" name="<?php echo esc_attr( $type ) ?>" value="<?php echo esc_attr( $value ) ?>" />
244
+ <?php
245
+ break;
246
+ }
247
+
248
+ // Print the close tag of field container
249
+ echo 'edit' == $form ? '</td></tr>' : '</div>';
250
+ }
251
+
252
+ /**
253
+ * Save term meta
254
+ *
255
+ * @param int $term_id
256
+ * @param int $tt_id
257
+ */
258
+ public function save_term_meta( $term_id, $tt_id ) {
259
+ foreach ( TA_WCVS()->types as $type => $label ) {
260
+ if ( isset( $_POST[$type] ) ) {
261
+ update_term_meta( $term_id, $type, sanitize_text_field( $_POST[$type] ) );
262
+ }
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Add thumbnail column to column list
268
+ *
269
+ * @param array $columns
270
+ *
271
+ * @return array
272
+ */
273
+ public function add_attribute_columns( $columns ) {
274
+ $new_columns = array();
275
+ $new_columns['cb'] = $columns['cb'];
276
+ $new_columns['thumb'] = '';
277
+ unset( $columns['cb'] );
278
+
279
+ return array_merge( $new_columns, $columns );
280
+ }
281
+
282
+ /**
283
+ * Render thumbnail HTML depend on attribute type
284
+ *
285
+ * @param $columns
286
+ * @param $column
287
+ * @param $term_id
288
+ */
289
+ public function add_attribute_column_content( $columns, $column, $term_id ) {
290
+ if ( 'thumb' !== $column ) {
291
+ return $columns;
292
+ }
293
+
294
+ $attr = TA_WCVS()->get_tax_attribute( $_REQUEST['taxonomy'] );
295
+ $value = get_term_meta( $term_id, $attr->attribute_type, true );
296
+
297
+ switch ( $attr->attribute_type ) {
298
+ case 'color':
299
+ printf( '<div class="swatch-preview swatch-color" style="background-color:%s;"></div>', esc_attr( $value ) );
300
+ break;
301
+
302
+ case 'image':
303
+ $image = $value ? wp_get_attachment_image_src( $value ) : '';
304
+ $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
305
+ printf( '<img class="swatch-preview swatch-image" src="%s" width="44px" height="44px">', esc_url( $image ) );
306
+ break;
307
+
308
+ case 'label':
309
+ printf( '<div class="swatch-preview swatch-label">%s</div>', esc_html( $value ) );
310
+ break;
311
+ }
312
+ }
313
+ }
includes/class-frontend.php CHANGED
@@ -1,169 +1,169 @@
1
- <?php
2
-
3
- /**
4
- * Class TA_WC_Variation_Swatches_Frontend
5
- */
6
- class TA_WC_Variation_Swatches_Frontend {
7
- /**
8
- * The single instance of the class
9
- *
10
- * @var TA_WC_Variation_Swatches_Frontend
11
- */
12
- protected static $instance = null;
13
-
14
- /**
15
- * Main instance
16
- *
17
- * @return TA_WC_Variation_Swatches_Frontend
18
- */
19
- public static function instance() {
20
- if ( null == self::$instance ) {
21
- self::$instance = new self();
22
- }
23
-
24
- return self::$instance;
25
- }
26
-
27
- /**
28
- * Class constructor.
29
- */
30
- public function __construct() {
31
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
32
-
33
- add_filter( 'woocommerce_dropdown_variation_attribute_options_html', array( $this, 'get_swatch_html' ), 100, 2 );
34
- add_filter( 'tawcvs_swatch_html', array( $this, 'swatch_html' ), 5, 4 );
35
- }
36
-
37
- /**
38
- * Enqueue scripts and stylesheets
39
- */
40
- public function enqueue_scripts() {
41
- wp_enqueue_style( 'tawcvs-frontend', plugins_url( 'assets/css/frontend.css', TAWC_VS_PLUGIN_FILE ), array(), '20200222' );
42
- wp_enqueue_script( 'tawcvs-frontend', plugins_url( 'assets/js/frontend.js', TAWC_VS_PLUGIN_FILE ), array( 'jquery' ), '20200317', true );
43
- }
44
-
45
- /**
46
- * Filter function to add swatches bellow the default selector
47
- *
48
- * @param $html
49
- * @param $args
50
- *
51
- * @return string
52
- */
53
- public function get_swatch_html( $html, $args ) {
54
- $swatch_types = TA_WCVS()->types;
55
- $attr = TA_WCVS()->get_tax_attribute( $args['attribute'] );
56
-
57
- // Return if this is normal attribute
58
- if ( empty( $attr ) ) {
59
- return $html;
60
- }
61
-
62
- if ( ! array_key_exists( $attr->attribute_type, $swatch_types ) ) {
63
- return $html;
64
- }
65
-
66
- $options = $args['options'];
67
- $product = $args['product'];
68
- $attribute = $args['attribute'];
69
- $class = "variation-selector variation-select-{$attr->attribute_type}";
70
- $swatches = '';
71
-
72
- // Add new option for tooltip to $args variable.
73
- $args['tooltip'] = wc_string_to_bool( get_option( 'tawcvs_enable_tooltip', 'yes' ) );
74
-
75
- if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
76
- $attributes = $product->get_variation_attributes();
77
- $options = $attributes[$attribute];
78
- }
79
-
80
- if ( array_key_exists( $attr->attribute_type, $swatch_types ) ) {
81
- if ( ! empty( $options ) && $product && taxonomy_exists( $attribute ) ) {
82
- // Get terms if this is a taxonomy - ordered. We need the names too.
83
- $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
84
-
85
- foreach ( $terms as $term ) {
86
- if ( in_array( $term->slug, $options ) ) {
87
- $swatches .= apply_filters( 'tawcvs_swatch_html', '', $term, $attr->attribute_type, $args );
88
- }
89
- }
90
- }
91
-
92
- if ( ! empty( $swatches ) ) {
93
- $class .= ' hidden';
94
- $swatches = '<div class="tawcvs-swatches" data-attribute_name="attribute_' . esc_attr( $attribute ) . '">' . $swatches . '</div>';
95
- $html = '<div class="' . esc_attr( $class ) . '">' . $html . '</div>' . $swatches;
96
- }
97
- }
98
-
99
- return $html;
100
- }
101
-
102
- /**
103
- * Print HTML of a single swatch
104
- *
105
- * @param $html
106
- * @param $term
107
- * @param $type
108
- * @param $args
109
- *
110
- * @return string
111
- */
112
- public function swatch_html( $html, $term, $type, $args ) {
113
- $selected = sanitize_title( $args['selected'] ) == $term->slug ? 'selected' : '';
114
- $name = esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) );
115
- $tooltip = '';
116
-
117
- if ( ! empty( $args['tooltip'] ) ) {
118
- $tooltip = '<span class="swatch__tooltip">' . ( $term->description ? $term->description : $name ) . '</span>';
119
- }
120
-
121
- switch ( $type ) {
122
- case 'color':
123
- $color = get_term_meta( $term->term_id, 'color', true );
124
- list( $r, $g, $b ) = sscanf( $color, "#%02x%02x%02x" );
125
- $html = sprintf(
126
- '<span class="swatch swatch-color swatch-%s %s" style="background-color:%s;color:%s;" data-value="%s">%s%s</span>',
127
- esc_attr( $term->slug ),
128
- $selected,
129
- esc_attr( $color ),
130
- "rgba($r,$g,$b,0.5)",
131
- esc_attr( $term->slug ),
132
- $name,
133
- $tooltip
134
- );
135
- break;
136
-
137
- case 'image':
138
- $image = get_term_meta( $term->term_id, 'image', true );
139
- $image = $image ? wp_get_attachment_image_src( $image ) : '';
140
- $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
141
- $html = sprintf(
142
- '<span class="swatch swatch-image swatch-%s %s" data-value="%s"><img src="%s" alt="%s">%s%s</span>',
143
- esc_attr( $term->slug ),
144
- $selected,
145
- esc_attr( $term->slug ),
146
- esc_url( $image ),
147
- esc_attr( $name ),
148
- $name,
149
- $tooltip
150
- );
151
- break;
152
-
153
- case 'label':
154
- $label = get_term_meta( $term->term_id, 'label', true );
155
- $label = $label ? $label : $name;
156
- $html = sprintf(
157
- '<span class="swatch swatch-label swatch-%s %s" data-value="%s">%s%s</span>',
158
- esc_attr( $term->slug ),
159
- $selected,
160
- esc_attr( $term->slug ),
161
- esc_html( $label ),
162
- $tooltip
163
- );
164
- break;
165
- }
166
-
167
- return $html;
168
- }
169
  }
1
+ <?php
2
+
3
+ /**
4
+ * Class TA_WC_Variation_Swatches_Frontend
5
+ */
6
+ class TA_WC_Variation_Swatches_Frontend {
7
+ /**
8
+ * The single instance of the class
9
+ *
10
+ * @var TA_WC_Variation_Swatches_Frontend
11
+ */
12
+ protected static $instance = null;
13
+
14
+ /**
15
+ * Main instance
16
+ *
17
+ * @return TA_WC_Variation_Swatches_Frontend
18
+ */
19
+ public static function instance() {
20
+ if ( null == self::$instance ) {
21
+ self::$instance = new self();
22
+ }
23
+
24
+ return self::$instance;
25
+ }
26
+
27
+ /**
28
+ * Class constructor.
29
+ */
30
+ public function __construct() {
31
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
32
+
33
+ add_filter( 'woocommerce_dropdown_variation_attribute_options_html', array( $this, 'get_swatch_html' ), 100, 2 );
34
+ add_filter( 'tawcvs_swatch_html', array( $this, 'swatch_html' ), 5, 4 );
35
+ }
36
+
37
+ /**
38
+ * Enqueue scripts and stylesheets
39
+ */
40
+ public function enqueue_scripts() {
41
+ wp_enqueue_style( 'tawcvs-frontend', plugins_url( 'assets/css/frontend.css', TAWC_VS_PLUGIN_FILE ), array(), '20200222' );
42
+ wp_enqueue_script( 'tawcvs-frontend', plugins_url( 'assets/js/frontend.js', TAWC_VS_PLUGIN_FILE ), array( 'jquery' ), '20200317', true );
43
+ }
44
+
45
+ /**
46
+ * Filter function to add swatches bellow the default selector
47
+ *
48
+ * @param $html
49
+ * @param $args
50
+ *
51
+ * @return string
52
+ */
53
+ public function get_swatch_html( $html, $args ) {
54
+ $swatch_types = TA_WCVS()->types;
55
+ $attr = TA_WCVS()->get_tax_attribute( $args['attribute'] );
56
+
57
+ // Return if this is normal attribute
58
+ if ( empty( $attr ) ) {
59
+ return $html;
60
+ }
61
+
62
+ if ( ! array_key_exists( $attr->attribute_type, $swatch_types ) ) {
63
+ return $html;
64
+ }
65
+
66
+ $options = $args['options'];
67
+ $product = $args['product'];
68
+ $attribute = $args['attribute'];
69
+ $class = "variation-selector variation-select-{$attr->attribute_type}";
70
+ $swatches = '';
71
+
72
+ // Add new option for tooltip to $args variable.
73
+ $args['tooltip'] = wc_string_to_bool( get_option( 'tawcvs_enable_tooltip', 'yes' ) );
74
+
75
+ if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
76
+ $attributes = $product->get_variation_attributes();
77
+ $options = $attributes[$attribute];
78
+ }
79
+
80
+ if ( array_key_exists( $attr->attribute_type, $swatch_types ) ) {
81
+ if ( ! empty( $options ) && $product && taxonomy_exists( $attribute ) ) {
82
+ // Get terms if this is a taxonomy - ordered. We need the names too.
83
+ $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
84
+
85
+ foreach ( $terms as $term ) {
86
+ if ( in_array( $term->slug, $options ) ) {
87
+ $swatches .= apply_filters( 'tawcvs_swatch_html', '', $term, $attr->attribute_type, $args );
88
+ }
89
+ }
90
+ }
91
+
92
+ if ( ! empty( $swatches ) ) {
93
+ $class .= ' hidden';
94
+ $swatches = '<div class="tawcvs-swatches" data-attribute_name="attribute_' . esc_attr( $attribute ) . '">' . $swatches . '</div>';
95
+ $html = '<div class="' . esc_attr( $class ) . '">' . $html . '</div>' . $swatches;
96
+ }
97
+ }
98
+
99
+ return $html;
100
+ }
101
+
102
+ /**
103
+ * Print HTML of a single swatch
104
+ *
105
+ * @param $html
106
+ * @param $term
107
+ * @param $type
108
+ * @param $args
109
+ *
110
+ * @return string
111
+ */
112
+ public function swatch_html( $html, $term, $type, $args ) {
113
+ $selected = sanitize_title( $args['selected'] ) == $term->slug ? 'selected' : '';
114
+ $name = esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) );
115
+ $tooltip = '';
116
+
117
+ if ( ! empty( $args['tooltip'] ) ) {
118
+ $tooltip = '<span class="swatch__tooltip">' . ( $term->description ? $term->description : $name ) . '</span>';
119
+ }
120
+
121
+ switch ( $type ) {
122
+ case 'color':
123
+ $color = get_term_meta( $term->term_id, 'color', true );
124
+ list( $r, $g, $b ) = sscanf( $color, "#%02x%02x%02x" );
125
+ $html = sprintf(
126
+ '<span class="swatch swatch-color swatch-%s %s" style="background-color:%s;color:%s;" data-value="%s">%s%s</span>',
127
+ esc_attr( $term->slug ),
128
+ $selected,
129
+ esc_attr( $color ),
130
+ "rgba($r,$g,$b,0.5)",
131
+ esc_attr( $term->slug ),
132
+ $name,
133
+ $tooltip
134
+ );
135
+ break;
136
+
137
+ case 'image':
138
+ $image = get_term_meta( $term->term_id, 'image', true );
139
+ $image = $image ? wp_get_attachment_image_src( $image ) : '';
140
+ $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
141
+ $html = sprintf(
142
+ '<span class="swatch swatch-image swatch-%s %s" data-value="%s"><img src="%s" alt="%s">%s%s</span>',
143
+ esc_attr( $term->slug ),
144
+ $selected,
145
+ esc_attr( $term->slug ),
146
+ esc_url( $image ),
147
+ esc_attr( $name ),
148
+ $name,
149
+ $tooltip
150
+ );
151
+ break;
152
+
153
+ case 'label':
154
+ $label = get_term_meta( $term->term_id, 'label', true );
155
+ $label = $label ? $label : $name;
156
+ $html = sprintf(
157
+ '<span class="swatch swatch-label swatch-%s %s" data-value="%s">%s%s</span>',
158
+ esc_attr( $term->slug ),
159
+ $selected,
160
+ esc_attr( $term->slug ),
161
+ esc_html( $label ),
162
+ $tooltip
163
+ );
164
+ break;
165
+ }
166
+
167
+ return $html;
168
+ }
169
  }
includes/class-variation-swatches.php CHANGED
@@ -1,141 +1,141 @@
1
- <?php
2
-
3
- /**
4
- * The main plugin class
5
- */
6
- final class TA_WC_Variation_Swatches {
7
- /**
8
- * The single instance of the class
9
- *
10
- * @var TA_WC_Variation_Swatches
11
- */
12
- protected static $instance = null;
13
-
14
- /**
15
- * Extra attribute types
16
- *
17
- * @var array
18
- */
19
- public $types = array();
20
-
21
- /**
22
- * Main instance
23
- *
24
- * @return TA_WC_Variation_Swatches
25
- */
26
- public static function instance() {
27
- if ( null == self::$instance ) {
28
- self::$instance = new self();
29
- }
30
-
31
- return self::$instance;
32
- }
33
-
34
- /**
35
- * Class constructor.
36
- */
37
- public function __construct() {
38
- $this->types = array(
39
- 'color' => esc_html__( 'Color', 'wcvs' ),
40
- 'image' => esc_html__( 'Image', 'wcvs' ),
41
- 'label' => esc_html__( 'Label', 'wcvs' ),
42
- );
43
-
44
- $this->includes();
45
- $this->init_hooks();
46
- }
47
-
48
- /**
49
- * Include required core files used in admin and on the frontend.
50
- */
51
- public function includes() {
52
- require_once dirname( __FILE__ ) . '/class-frontend.php';
53
-
54
- if ( is_admin() ) {
55
- require_once dirname( __FILE__ ) . '/class-admin.php';
56
- }
57
- }
58
-
59
- /**
60
- * Initialize hooks
61
- */
62
- public function init_hooks() {
63
- add_action( 'init', array( $this, 'load_textdomain' ) );
64
-
65
- add_filter( 'product_attributes_type_selector', array( $this, 'add_attribute_types' ) );
66
-
67
- if ( is_admin() ) {
68
- add_action( 'init', array( 'TA_WC_Variation_Swatches_Admin', 'instance' ) );
69
- }
70
-
71
- if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
72
- add_action( 'init', array( 'TA_WC_Variation_Swatches_Frontend', 'instance' ) );
73
- }
74
- }
75
-
76
- /**
77
- * Load plugin text domain
78
- */
79
- public function load_textdomain() {
80
- load_plugin_textdomain( 'wcvs', false, dirname( plugin_basename( TAWC_VS_PLUGIN_FILE ) ) . '/languages/' );
81
- }
82
-
83
- /**
84
- * Add extra attribute types
85
- * Add color, image and label type
86
- *
87
- * @param array $types
88
- *
89
- * @return array
90
- */
91
- public function add_attribute_types( $types ) {
92
- $types = array_merge( $types, $this->types );
93
-
94
- return $types;
95
- }
96
-
97
- /**
98
- * Get attribute's properties
99
- *
100
- * @param string $taxonomy
101
- *
102
- * @return object
103
- */
104
- public function get_tax_attribute( $taxonomy ) {
105
- global $wpdb;
106
-
107
- $attr = substr( $taxonomy, 3 );
108
- $attr = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = %s", $attr ) );
109
-
110
- return $attr;
111
- }
112
-
113
- /**
114
- * Instance of admin
115
- *
116
- * @return object
117
- */
118
- public function admin() {
119
- return TA_WC_Variation_Swatches_Admin::instance();
120
- }
121
-
122
- /**
123
- * Instance of frontend
124
- *
125
- * @return object
126
- */
127
- public function frontend() {
128
- return TA_WC_Variation_Swatches_Frontend::instance();
129
- }
130
- }
131
-
132
- if ( ! function_exists( 'TA_WCVS' ) ) {
133
- /**
134
- * Main instance of plugin
135
- *
136
- * @return TA_WC_Variation_Swatches
137
- */
138
- function TA_WCVS() {
139
- return TA_WC_Variation_Swatches::instance();
140
- }
141
  }
1
+ <?php
2
+
3
+ /**
4
+ * The main plugin class
5
+ */
6
+ final class TA_WC_Variation_Swatches {
7
+ /**
8
+ * The single instance of the class
9
+ *
10
+ * @var TA_WC_Variation_Swatches
11
+ */
12
+ protected static $instance = null;
13
+
14
+ /**
15
+ * Extra attribute types
16
+ *
17
+ * @var array
18
+ */
19
+ public $types = array();
20
+
21
+ /**
22
+ * Main instance
23
+ *
24
+ * @return TA_WC_Variation_Swatches
25
+ */
26
+ public static function instance() {
27
+ if ( null == self::$instance ) {
28
+ self::$instance = new self();
29
+ }
30
+
31
+ return self::$instance;
32
+ }
33
+
34
+ /**
35
+ * Class constructor.
36
+ */
37
+ public function __construct() {
38
+ $this->types = array(
39
+ 'color' => esc_html__( 'Color', 'wcvs' ),
40
+ 'image' => esc_html__( 'Image', 'wcvs' ),
41
+ 'label' => esc_html__( 'Label', 'wcvs' ),
42
+ );
43
+
44
+ $this->includes();
45
+ $this->init_hooks();
46
+ }
47
+
48
+ /**
49
+ * Include required core files used in admin and on the frontend.
50
+ */
51
+ public function includes() {
52
+ require_once dirname( __FILE__ ) . '/class-frontend.php';
53
+
54
+ if ( is_admin() ) {
55
+ require_once dirname( __FILE__ ) . '/class-admin.php';
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Initialize hooks
61
+ */
62
+ public function init_hooks() {
63
+ add_action( 'init', array( $this, 'load_textdomain' ) );
64
+
65
+ add_filter( 'product_attributes_type_selector', array( $this, 'add_attribute_types' ) );
66
+
67
+ if ( is_admin() ) {
68
+ add_action( 'init', array( 'TA_WC_Variation_Swatches_Admin', 'instance' ) );
69
+ }
70
+
71
+ if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
72
+ add_action( 'init', array( 'TA_WC_Variation_Swatches_Frontend', 'instance' ) );
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Load plugin text domain
78
+ */
79
+ public function load_textdomain() {
80
+ load_plugin_textdomain( 'wcvs', false, dirname( plugin_basename( TAWC_VS_PLUGIN_FILE ) ) . '/languages/' );
81
+ }
82
+
83
+ /**
84
+ * Add extra attribute types
85
+ * Add color, image and label type
86
+ *
87
+ * @param array $types
88
+ *
89
+ * @return array
90
+ */
91
+ public function add_attribute_types( $types ) {
92
+ $types = array_merge( $types, $this->types );
93
+
94
+ return $types;
95
+ }
96
+
97
+ /**
98
+ * Get attribute's properties
99
+ *
100
+ * @param string $taxonomy
101
+ *
102
+ * @return object
103
+ */
104
+ public function get_tax_attribute( $taxonomy ) {
105
+ global $wpdb;
106
+
107
+ $attr = substr( $taxonomy, 3 );
108
+ $attr = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = %s", $attr ) );
109
+
110
+ return $attr;
111
+ }
112
+
113
+ /**
114
+ * Instance of admin
115
+ *
116
+ * @return object
117
+ */
118
+ public function admin() {
119
+ return TA_WC_Variation_Swatches_Admin::instance();
120
+ }
121
+
122
+ /**
123
+ * Instance of frontend
124
+ *
125
+ * @return object
126
+ */
127
+ public function frontend() {
128
+ return TA_WC_Variation_Swatches_Frontend::instance();
129
+ }
130
+ }
131
+
132
+ if ( ! function_exists( 'TA_WCVS' ) ) {
133
+ /**
134
+ * Main instance of plugin
135
+ *
136
+ * @return TA_WC_Variation_Swatches
137
+ */
138
+ function TA_WCVS() {
139
+ return TA_WC_Variation_Swatches::instance();
140
+ }
141
  }
readme.txt CHANGED
@@ -1,118 +1,121 @@
1
- === Variation Swatches for WooCommerce ===
2
- Contributors: themealien, coderexco
3
- Tags: woocommerce, product attribute, product color, product size, variation swatches, variable products
4
- Requires at least: 4.5
5
- Tested up to: 5.4.1
6
- Stable tag: 1.0.10
7
- WC requires at least: 3.2.0
8
- WC tested up to: 4.1.0
9
- License: GPLv2 or later
10
- License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
-
12
- An extension of WooCommerce that make variable products be more beauty and friendly to customers.
13
-
14
- == Description ==
15
-
16
- Variation Swatches for WooCommerce plugin provides a much nicer way to display variations of variable products. This plugin will help you select style for each attribute as color, image or label. With this plugin, you can present product colors, sizes, styles and many things in a better way which is not supported by WooCommerce.
17
- This plugin only adds more options to show product variations with swatches. It doesn't touch the default drop-down style of WooCommerce.
18
-
19
- With a friendly and easy-to-use interface, you can add default color, image or label to each attribute in the attributes management page. It can also helps you pick the right style for quick-add attribute right inside the editing product page.
20
-
21
- **Features provided with this plugin:**
22
-
23
- * Completely integrate with WooCommerce plugin
24
- * Work on variable product only
25
- * Create attribute color swatches
26
- * Create attribute image swatches
27
- * Create attribute label/text swatches
28
- * Manage attribute globally
29
- * Create new attribute swatch in product editing page
30
-
31
-
32
- == Installation ==
33
-
34
- = Automatic installation =
35
-
36
- Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser.
37
-
38
- 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
39
- 1. In the search field type "Variation Swatches for WooCommerce" and click Search Plugins.
40
- 1. Once you’ve found it, you can install it by simply clicking Install Now button.
41
-
42
- = Manual Installation =
43
-
44
- 1. Download the Variation Swatches for WooCommerce plugin to your desktop.
45
- 1. Extract the plugin folder to your desktop.
46
- 1. Read through the "readme" file thoroughly to ensure you follow the installation instructions.
47
- 1. With your FTP program, upload the Plugin folder to the wp-content/plugins folder in your WordPress directory online.
48
- 1. Go to Plugins screen and find the "Variation Swatches for WooCommerce" in the list.
49
- 1. Click Activate to activate it.
50
-
51
- = Config attributes =
52
-
53
- Even this plugin has been installed and activated on your site, variable products will still show dropdowns if you've not configured product attributes.
54
-
55
- 1. Log in to your WordPress dashboard, navigate to the Products menu and click Attributes.
56
- 1. Click to attribute name to edit an exists attribute or in the Add New Attribute form you will see the default Type selector.
57
- 1. Click to that Type selector to change attribute's type. Besides default options Select and Text, there are more 3 options Color, Image, Label to choose.
58
- 1. Select the suitable type for your attribute and click Save Change/Add attribute
59
- 1. Go back to manage attributes screen. Click the cog icon on the right side of attribute to start editing terms.
60
- 1. Start adding new terms or editing exists terms. There is will be a new option at the end of form that let you choose the color, upload image or type the label for those terms.
61
-
62
-
63
- == Frequently Asked Questions ==
64
-
65
- = Will this plugin work with my theme? =
66
- Yes, it will work with any theme, but may require some styling to make it match nicely.
67
-
68
- == Screenshots ==
69
-
70
- 1. Variations on frontend
71
- 1. Add new attribute
72
- 1. Edit Attribute
73
- 1. Attribute color
74
- 1. Attribute label
75
- 1. Attribute image
76
- 1. Add new attribute color when edit a product
77
-
78
- == Changelog ==
79
-
80
- = 1.0.10 =
81
- * Fix - The issue of numeric attributes are not selectable.
82
- * Fix - Display custom column content incorrectly in admin area.
83
-
84
- = 1.0.9 =
85
- * Fix - Sometimes can't select attributes.
86
-
87
- = 1.0.8 =
88
- * Enhancement - Disable invalid swatches base on select ones.
89
- * Fix - Can't deactivate plugin without WooCommerce installed.
90
-
91
- = 1.0.7 =
92
- * Tweak - Update CSS for active state of swatches, remove the box shadow.
93
- * Fix - Tooltip is not showed on image swatches.
94
-
95
- = 1.0.6 =
96
- * New - Add a notice in admin area to restore attribute types after re-activating the plugin.
97
- * Tweak - Rename the tooltip CSS class following WooCommerce standard.
98
- * Tweak - Remove opacity from swatches.
99
- * Security - Using $wpdb->prepare to get attribute data.
100
-
101
- = 1.0.5 =
102
- * Add tooltip
103
-
104
- = 1.0.4 =
105
- * Fix the issue of product attributes are not saved.
106
- * Restore attribute type to "Select" if the plugin is deactivated.
107
-
108
- = 1.0.3 =
109
- * Fix the issue of adding attributes in the "Attributes" tab
110
-
111
- = 1.0.2 =
112
- * Support WooCommerce 3.0
113
-
114
- = 1.0.1 =
115
- * Add "swatches-support" class to the variations form
116
-
117
- = 1.0.0 =
 
 
 
118
  * Initial release.
1
+ === Variation Swatches for WooCommerce ===
2
+ Contributors: themealien, mehbubrashid
3
+ Tags: woocommerce, product attribute, product color, product size, variation swatches, variable products
4
+ Requires at least: 4.5
5
+ Tested up to: 5.7
6
+ Stable tag: 1.0.11
7
+ WC requires at least: 3.2.0
8
+ WC tested up to: 5.4.1
9
+ License: GPLv2 or later
10
+ License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
+
12
+ An extension of WooCommerce that make variable products be more beauty and friendly to customers.
13
+
14
+ == Description ==
15
+
16
+ Variation Swatches for WooCommerce plugin provides a much nicer way to display variations of variable products. This plugin will help you select style for each attribute as color, image or label. With this plugin, you can present product colors, sizes, styles and many things in a better way which is not supported by WooCommerce.
17
+ This plugin only adds more options to show product variations with swatches. It doesn't touch the default drop-down style of WooCommerce.
18
+
19
+ With a friendly and easy-to-use interface, you can add default color, image or label to each attribute in the attributes management page. It can also helps you pick the right style for quick-add attribute right inside the editing product page.
20
+
21
+ **Features provided with this plugin:**
22
+
23
+ * Completely integrate with WooCommerce plugin
24
+ * Work on variable product only
25
+ * Create attribute color swatches
26
+ * Create attribute image swatches
27
+ * Create attribute label/text swatches
28
+ * Manage attribute globally
29
+ * Create new attribute swatch in product editing page
30
+
31
+
32
+ == Installation ==
33
+
34
+ = Automatic installation =
35
+
36
+ Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser.
37
+
38
+ 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
39
+ 1. In the search field type "Variation Swatches for WooCommerce" and click Search Plugins.
40
+ 1. Once you’ve found it, you can install it by simply clicking Install Now button.
41
+
42
+ = Manual Installation =
43
+
44
+ 1. Download the Variation Swatches for WooCommerce plugin to your desktop.
45
+ 1. Extract the plugin folder to your desktop.
46
+ 1. Read through the "readme" file thoroughly to ensure you follow the installation instructions.
47
+ 1. With your FTP program, upload the Plugin folder to the wp-content/plugins folder in your WordPress directory online.
48
+ 1. Go to Plugins screen and find the "Variation Swatches for WooCommerce" in the list.
49
+ 1. Click Activate to activate it.
50
+
51
+ = Config attributes =
52
+
53
+ Even this plugin has been installed and activated on your site, variable products will still show dropdowns if you've not configured product attributes.
54
+
55
+ 1. Log in to your WordPress dashboard, navigate to the Products menu and click Attributes.
56
+ 1. Click to attribute name to edit an exists attribute or in the Add New Attribute form you will see the default Type selector.
57
+ 1. Click to that Type selector to change attribute's type. Besides default options Select and Text, there are more 3 options Color, Image, Label to choose.
58
+ 1. Select the suitable type for your attribute and click Save Change/Add attribute
59
+ 1. Go back to manage attributes screen. Click the cog icon on the right side of attribute to start editing terms.
60
+ 1. Start adding new terms or editing exists terms. There is will be a new option at the end of form that let you choose the color, upload image or type the label for those terms.
61
+
62
+
63
+ == Frequently Asked Questions ==
64
+
65
+ = Will this plugin work with my theme? =
66
+ Yes, it will work with any theme, but may require some styling to make it match nicely.
67
+
68
+ == Screenshots ==
69
+
70
+ 1. Variations on frontend
71
+ 1. Add new attribute
72
+ 1. Edit Attribute
73
+ 1. Attribute color
74
+ 1. Attribute label
75
+ 1. Attribute image
76
+ 1. Add new attribute color when edit a product
77
+
78
+ == Changelog ==
79
+
80
+ = 1.0.11 =
81
+ * Compatible with latest wordpress.
82
+
83
+ = 1.0.10 =
84
+ * Fix - The issue of numeric attributes are not selectable.
85
+ * Fix - Display custom column content incorrectly in admin area.
86
+
87
+ = 1.0.9 =
88
+ * Fix - Sometimes can't select attributes.
89
+
90
+ = 1.0.8 =
91
+ * Enhancement - Disable invalid swatches base on select ones.
92
+ * Fix - Can't deactivate plugin without WooCommerce installed.
93
+
94
+ = 1.0.7 =
95
+ * Tweak - Update CSS for active state of swatches, remove the box shadow.
96
+ * Fix - Tooltip is not showed on image swatches.
97
+
98
+ = 1.0.6 =
99
+ * New - Add a notice in admin area to restore attribute types after re-activating the plugin.
100
+ * Tweak - Rename the tooltip CSS class following WooCommerce standard.
101
+ * Tweak - Remove opacity from swatches.
102
+ * Security - Using $wpdb->prepare to get attribute data.
103
+
104
+ = 1.0.5 =
105
+ * Add tooltip
106
+
107
+ = 1.0.4 =
108
+ * Fix the issue of product attributes are not saved.
109
+ * Restore attribute type to "Select" if the plugin is deactivated.
110
+
111
+ = 1.0.3 =
112
+ * Fix the issue of adding attributes in the "Attributes" tab
113
+
114
+ = 1.0.2 =
115
+ * Support WooCommerce 3.0
116
+
117
+ = 1.0.1 =
118
+ * Add "swatches-support" class to the variations form
119
+
120
+ = 1.0.0 =
121
  * Initial release.
uninstall.php CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
- /**
3
- * Uninstall plugin
4
- */
5
-
6
- // If uninstall not called from WordPress exit
7
- if( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
8
- exit;
9
- }
10
-
11
- global $wpdb;
12
-
13
- //change to standard select type custom attributes
14
- $table = $wpdb->prefix . 'woocommerce_attribute_taxonomies';
15
- $update = "UPDATE `$table` SET `attribute_type` = 'select' WHERE `attribute_type` != 'text'";
16
  $wpdb->query( $update );
1
+ <?php
2
+ /**
3
+ * Uninstall plugin
4
+ */
5
+
6
+ // If uninstall not called from WordPress exit
7
+ if( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
8
+ exit;
9
+ }
10
+
11
+ global $wpdb;
12
+
13
+ //change to standard select type custom attributes
14
+ $table = $wpdb->prefix . 'woocommerce_attribute_taxonomies';
15
+ $update = "UPDATE `$table` SET `attribute_type` = 'select' WHERE `attribute_type` != 'text'";
16
  $wpdb->query( $update );
variation-swatches-for-woocommerce.php CHANGED
@@ -1,152 +1,152 @@
1
- <?php
2
- /**
3
- * Plugin Name: Variation Swatcher for WooCommerce
4
- * Plugin URI: http://themealien.com/wordpress-plugin/woocommerce-variation-swatches
5
- * Description: An extension of WooCommerce to make variable products be more beauty and friendly to users.
6
- * Version: 1.0.10
7
- * Author: ThemeAlien
8
- * Author URI: http://themealien.com/
9
- * Requires at least: 4.5
10
- * Tested up to: 5.4.1
11
- * Text Domain: wcvs
12
- * Domain Path: /languages
13
- * WC requires at least: 3.0.0
14
- * WC tested up to: 4.1.1
15
- *
16
- * License: GPLv2 or later
17
- * License URI: https://www.gnu.org/licenses/gpl-2.0.html
18
- */
19
-
20
- if ( ! defined( 'ABSPATH' ) ) {
21
- exit; // Exit if accessed directly.
22
- }
23
-
24
- // Define TAWC_DEALS_PLUGIN_FILE
25
- if ( ! defined( 'TAWC_VS_PLUGIN_FILE' ) ) {
26
- define( 'TAWC_VS_PLUGIN_FILE', __FILE__ );
27
- }
28
-
29
- if ( ! function_exists( 'ta_wc_variation_swatches_wc_notice' ) ) {
30
- /**
31
- * Display notice in case of WooCommerce plugin is not activated
32
- */
33
- function ta_wc_variation_swatches_wc_notice() {
34
- ?>
35
-
36
- <div class="error">
37
- <p><?php esc_html_e( 'Variation Swatcher for WooCommerce is enabled but not effective. It requires WooCommerce in order to work.', 'wcvs' ); ?></p>
38
- </div>
39
-
40
- <?php
41
- }
42
- }
43
-
44
- if ( ! function_exists( 'ta_wc_variation_swatches_pro_notice' ) ) {
45
- /**
46
- * Display notice in case of WooCommerce plugin is not activated
47
- */
48
- function ta_wc_variation_swatches_pro_notice() {
49
- ?>
50
-
51
- <div class="error">
52
- <p><?php esc_html_e( 'No need to activate the free version of Variation Swatcher for WooCommerce plugin while the pro version is activated.', 'wcvs' ); ?></p>
53
- </div>
54
-
55
- <?php
56
- }
57
- }
58
-
59
- if ( ! function_exists( 'ta_wc_variation_swatches_constructor' ) ) {
60
- /**
61
- * Construct plugin when plugins loaded in order to make sure WooCommerce API is fully loaded
62
- * Check if WooCommerce is not activated then show an admin notice
63
- * or create the main instance of plugin
64
- */
65
- function ta_wc_variation_swatches_constructor() {
66
- if ( ! function_exists( 'WC' ) ) {
67
- add_action( 'admin_notices', 'ta_wc_variation_swatches_wc_notice' );
68
- } elseif ( defined( 'TAWC_VS_PRO' ) ) {
69
- add_action( 'admin_notices', 'ta_wc_variation_swatches_pro_notice' );
70
- deactivate_plugins( plugin_basename( __FILE__ ) );
71
- } else {
72
- require_once plugin_dir_path( __FILE__ ) . '/includes/class-variation-swatches.php';
73
- TA_WCVS();
74
- }
75
- }
76
- }
77
-
78
- if ( ! function_exists( 'ta_wc_variation_swatches_deactivate' ) ) {
79
- /**
80
- * Deactivation hook.
81
- * Backup all unsupported types of attributes then reset them to "select".
82
- *
83
- * @param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
84
- * or just the current site. Multisite only. Default is false.
85
- */
86
- function ta_wc_variation_swatches_deactivate( $network_deactivating ) {
87
- // Early return if WooCommerce is not activated.
88
- if ( ! class_exists( 'WooCommerce' ) ) {
89
- return;
90
- }
91
-
92
- global $wpdb;
93
-
94
- $blog_ids = array( 1 );
95
- $original_blog_id = 1;
96
- $network = false;
97
-
98
- if ( is_multisite() && $network_deactivating ) {
99
- $blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
100
- $original_blog_id = get_current_blog_id();
101
- $network = true;
102
- }
103
-
104
- foreach ( $blog_ids as $blog_id ) {
105
- if ( $network ) {
106
- switch_to_blog( $blog_id );
107
- }
108
-
109
- // Backup attribute types.
110
- $attributes = wc_get_attribute_taxonomies();
111
- $default_types = array( 'text', 'select' );
112
- $ta_wcvs_attributes = array();
113
-
114
- if ( ! empty( $attributes ) ) {
115
- foreach ( $attributes as $attribute ) {
116
- if ( ! in_array( $attribute->attribute_type, $default_types ) ) {
117
- $ta_wcvs_attributes[ $attribute->attribute_id ] = $attribute;
118
- }
119
- }
120
- }
121
-
122
- if ( ! empty( $ta_wcvs_attributes ) ) {
123
- set_transient( 'tawcvs_attribute_taxonomies', $ta_wcvs_attributes );
124
- delete_transient( 'wc_attribute_taxonomies' );
125
- update_option( 'tawcvs_backup_attributes_time', time() );
126
- }
127
-
128
- // Reset attributes.
129
- if ( ! empty( $ta_wcvs_attributes ) ) {
130
- foreach ( $ta_wcvs_attributes as $id => $attribute ) {
131
- $wpdb->update(
132
- $wpdb->prefix . 'woocommerce_attribute_taxonomies',
133
- array( 'attribute_type' => 'select' ),
134
- array( 'attribute_id' => $id ),
135
- array( '%s' ),
136
- array( '%d' )
137
- );
138
- }
139
- }
140
-
141
- // Delete the option of restoring time.
142
- delete_option( 'tawcvs_restore_attributes_time' );
143
- }
144
-
145
- if ( $network ) {
146
- switch_to_blog( $original_blog_id );
147
- }
148
- }
149
- }
150
-
151
- add_action( 'plugins_loaded', 'ta_wc_variation_swatches_constructor', 20 );
152
- register_deactivation_hook( __FILE__, 'ta_wc_variation_swatches_deactivate' );
1
+ <?php
2
+ /**
3
+ * Plugin Name: Variation Swatcher for WooCommerce
4
+ * Plugin URI: http://themealien.com/wordpress-plugin/woocommerce-variation-swatches
5
+ * Description: An extension of WooCommerce to make variable products be more beauty and friendly to users.
6
+ * Version: 1.0.11
7
+ * Author: ThemeAlien
8
+ * Author URI: http://themealien.com/
9
+ * Requires at least: 4.5
10
+ * Tested up to: 5.7
11
+ * Text Domain: wcvs
12
+ * Domain Path: /languages
13
+ * WC requires at least: 3.0.0
14
+ * WC tested up to: 5.4.1
15
+ *
16
+ * License: GPLv2 or later
17
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
18
+ */
19
+
20
+ if ( ! defined( 'ABSPATH' ) ) {
21
+ exit; // Exit if accessed directly.
22
+ }
23
+
24
+ // Define TAWC_DEALS_PLUGIN_FILE
25
+ if ( ! defined( 'TAWC_VS_PLUGIN_FILE' ) ) {
26
+ define( 'TAWC_VS_PLUGIN_FILE', __FILE__ );
27
+ }
28
+
29
+ if ( ! function_exists( 'ta_wc_variation_swatches_wc_notice' ) ) {
30
+ /**
31
+ * Display notice in case of WooCommerce plugin is not activated
32
+ */
33
+ function ta_wc_variation_swatches_wc_notice() {
34
+ ?>
35
+
36
+ <div class="error">
37
+ <p><?php esc_html_e( 'Variation Swatcher for WooCommerce is enabled but not effective. It requires WooCommerce in order to work.', 'wcvs' ); ?></p>
38
+ </div>
39
+
40
+ <?php
41
+ }
42
+ }
43
+
44
+ if ( ! function_exists( 'ta_wc_variation_swatches_pro_notice' ) ) {
45
+ /**
46
+ * Display notice in case of WooCommerce plugin is not activated
47
+ */
48
+ function ta_wc_variation_swatches_pro_notice() {
49
+ ?>
50
+
51
+ <div class="error">
52
+ <p><?php esc_html_e( 'No need to activate the free version of Variation Swatcher for WooCommerce plugin while the pro version is activated.', 'wcvs' ); ?></p>
53
+ </div>
54
+
55
+ <?php
56
+ }
57
+ }
58
+
59
+ if ( ! function_exists( 'ta_wc_variation_swatches_constructor' ) ) {
60
+ /**
61
+ * Construct plugin when plugins loaded in order to make sure WooCommerce API is fully loaded
62
+ * Check if WooCommerce is not activated then show an admin notice
63
+ * or create the main instance of plugin
64
+ */
65
+ function ta_wc_variation_swatches_constructor() {
66
+ if ( ! function_exists( 'WC' ) ) {
67
+ add_action( 'admin_notices', 'ta_wc_variation_swatches_wc_notice' );
68
+ } elseif ( defined( 'TAWC_VS_PRO' ) ) {
69
+ add_action( 'admin_notices', 'ta_wc_variation_swatches_pro_notice' );
70
+ deactivate_plugins( plugin_basename( __FILE__ ) );
71
+ } else {
72
+ require_once plugin_dir_path( __FILE__ ) . '/includes/class-variation-swatches.php';
73
+ TA_WCVS();
74
+ }
75
+ }
76
+ }
77
+
78
+ if ( ! function_exists( 'ta_wc_variation_swatches_deactivate' ) ) {
79
+ /**
80
+ * Deactivation hook.
81
+ * Backup all unsupported types of attributes then reset them to "select".
82
+ *
83
+ * @param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
84
+ * or just the current site. Multisite only. Default is false.
85
+ */
86
+ function ta_wc_variation_swatches_deactivate( $network_deactivating ) {
87
+ // Early return if WooCommerce is not activated.
88
+ if ( ! class_exists( 'WooCommerce' ) ) {
89
+ return;
90
+ }
91
+
92
+ global $wpdb;
93
+
94
+ $blog_ids = array( 1 );
95
+ $original_blog_id = 1;
96
+ $network = false;
97
+
98
+ if ( is_multisite() && $network_deactivating ) {
99
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}" );
100
+ $original_blog_id = get_current_blog_id();
101
+ $network = true;
102
+ }
103
+
104
+ foreach ( $blog_ids as $blog_id ) {
105
+ if ( $network ) {
106
+ switch_to_blog( $blog_id );
107
+ }
108
+
109
+ // Backup attribute types.
110
+ $attributes = wc_get_attribute_taxonomies();
111
+ $default_types = array( 'text', 'select' );
112
+ $ta_wcvs_attributes = array();
113
+
114
+ if ( ! empty( $attributes ) ) {
115
+ foreach ( $attributes as $attribute ) {
116
+ if ( ! in_array( $attribute->attribute_type, $default_types ) ) {
117
+ $ta_wcvs_attributes[ $attribute->attribute_id ] = $attribute;
118
+ }
119
+ }
120
+ }
121
+
122
+ if ( ! empty( $ta_wcvs_attributes ) ) {
123
+ set_transient( 'tawcvs_attribute_taxonomies', $ta_wcvs_attributes );
124
+ delete_transient( 'wc_attribute_taxonomies' );
125
+ update_option( 'tawcvs_backup_attributes_time', time() );
126
+ }
127
+
128
+ // Reset attributes.
129
+ if ( ! empty( $ta_wcvs_attributes ) ) {
130
+ foreach ( $ta_wcvs_attributes as $id => $attribute ) {
131
+ $wpdb->update(
132
+ $wpdb->prefix . 'woocommerce_attribute_taxonomies',
133
+ array( 'attribute_type' => 'select' ),
134
+ array( 'attribute_id' => $id ),
135
+ array( '%s' ),
136
+ array( '%d' )
137
+ );
138
+ }
139
+ }
140
+
141
+ // Delete the option of restoring time.
142
+ delete_option( 'tawcvs_restore_attributes_time' );
143
+ }
144
+
145
+ if ( $network ) {
146
+ switch_to_blog( $original_blog_id );
147
+ }
148
+ }
149
+ }
150
+
151
+ add_action( 'plugins_loaded', 'ta_wc_variation_swatches_constructor', 20 );
152
+ register_deactivation_hook( __FILE__, 'ta_wc_variation_swatches_deactivate' );