Variation Swatches for WooCommerce - Version 1.0.1

Version Description

  • Add "swatches-support" class to the variations form
Download this release

Release Info

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

Version 1.0.1

assets/css/admin.css ADDED
@@ -0,0 +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
+ }
assets/css/frontend.css ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .hidden {
2
+ display: none !important;
3
+ visibility: hidden !important;
4
+ }
5
+
6
+ .tawcvs-swatches {
7
+ overflow: hidden;
8
+ padding: 5px;
9
+ }
10
+
11
+ .tawcvs-swatches .swatch {
12
+ -webkit-transition: all 0.3s;
13
+ -moz-transition: all 0.3s;
14
+ -ms-transition: all 0.3s;
15
+ -o-transition: all 0.3s;
16
+ transition: all 0.3s;
17
+ -webkit-border-radius: 50%;
18
+ -moz-border-radius: 50%;
19
+ border-radius: 50%;
20
+ display: inline-block;
21
+ width: 30px;
22
+ height: 30px;
23
+ line-height: 30px;
24
+ text-align: center;
25
+ margin-right: 15px;
26
+ cursor: pointer;
27
+ border: 1px solid transparent;
28
+ position: relative;
29
+ opacity: 0.5;
30
+ }
31
+
32
+ .tawcvs-swatches .swatch.selected {
33
+ -webkit-box-shadow: 0 0 5px;
34
+ -moz-box-shadow: 0 0 5px;
35
+ box-shadow: 0 0 5px;
36
+ border-color: #999;
37
+ opacity: 1;
38
+ }
39
+
40
+ .tawcvs-swatches .swatch.disabled {
41
+ opacity: 0.1;
42
+ }
43
+
44
+ .tawcvs-swatches .swatch-color {
45
+ text-indent: -9999px;
46
+ }
47
+
48
+ .tawcvs-swatches .swatch-color.selected {
49
+ border-color: transparent;
50
+ }
51
+
52
+ .tawcvs-swatches .swatch-color.selected:before {
53
+ -webkit-transform: rotate(45deg);
54
+ -moz-transform: rotate(45deg);
55
+ transform: rotate(45deg);
56
+ content: "";
57
+ width: 6px;
58
+ height: 10px;
59
+ display: block;
60
+ border: solid #fff;
61
+ border-width: 0 2px 2px 0;
62
+ position: absolute;
63
+ top: 8px;
64
+ left: 11px;
65
+ }
66
+
67
+ .tawcvs-swatches .swatch-label {
68
+ background-color: #f1f1f1;
69
+ }
70
+
71
+ .tawcvs-swatches .swatch-image {
72
+ overflow: hidden;
73
+ }
assets/js/admin.js ADDED
@@ -0,0 +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.slug + '" 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 ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function ( $ ) {
2
+ 'use strict';
3
+
4
+ /**
5
+ * @TODO Code a function the 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
+ clicked = null,
11
+ selected = [];
12
+
13
+ $form
14
+ .addClass( 'swatches-support' )
15
+ .on( 'click', '.swatch', function ( e ) {
16
+ e.preventDefault();
17
+ var $el = $( this ),
18
+ $select = $el.closest( '.value' ).find( 'select' ),
19
+ attribute_name = $select.data( 'attribute_name' ) || $select.attr( 'name' ),
20
+ value = $el.data( 'value' );
21
+
22
+ $select.trigger( 'focusin' );
23
+
24
+ // Check if this combination is available
25
+ if ( ! $select.find( 'option[value="' + value + '"]' ).length ) {
26
+ $el.siblings( '.swatch' ).removeClass( 'selected' );
27
+ $select.val( '' ).change();
28
+ $form.trigger( 'tawcvs_no_matching_variations', [$el] );
29
+ return;
30
+ }
31
+
32
+ clicked = attribute_name;
33
+
34
+ if ( selected.indexOf( attribute_name ) === -1 ) {
35
+ selected.push(attribute_name);
36
+ }
37
+
38
+ if ( $el.hasClass( 'selected' ) ) {
39
+ $select.val( '' );
40
+ $el.removeClass( 'selected' );
41
+
42
+ delete selected[selected.indexOf(attribute_name)];
43
+ } else {
44
+ $el.addClass( 'selected' ).siblings( '.selected' ).removeClass( 'selected' );
45
+ $select.val( value );
46
+ }
47
+
48
+ $select.change();
49
+ } )
50
+ .on( 'click', '.reset_variations', function () {
51
+ $( this ).closest( '.variations_form' ).find( '.swatch.selected' ).removeClass( 'selected' );
52
+ selected = [];
53
+ } )
54
+ .on( 'tawcvs_no_matching_variations', function() {
55
+ window.alert( wc_add_to_cart_variation_params.i18n_no_matching_variations_text );
56
+ } );
57
+ } );
58
+ };
59
+
60
+ $( function () {
61
+ $( '.variations_form' ).tawcvs_variation_swatches_form();
62
+ $( document.body ).trigger( 'tawcvs_initialized' );
63
+ } );
64
+ })( jQuery );
includes/class-admin.php ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, 'init_attribute_hooks' ) );
32
+ add_action( 'admin_print_scripts', array( $this, 'enqueue_scripts' ) );
33
+ add_action( 'woocommerce_product_option_terms', array( $this, 'product_option_terms' ), 10, 2 );
34
+
35
+ // Display attribute fields
36
+ add_action( 'tawcvs_product_attribute_field', array( $this, 'attribute_fields' ), 10, 3 );
37
+
38
+ // ajax add attribute
39
+ add_action( 'wp_ajax_tawcvs_add_new_attribute', array( $this, 'add_new_attribute_ajax' ) );
40
+
41
+ add_action( 'admin_footer', array( $this, 'add_attribute_term_template' ) );
42
+ }
43
+
44
+ /**
45
+ * Init hooks for adding fields to attribute screen
46
+ * Save new term meta
47
+ * Add thumbnail column for attribute term
48
+ */
49
+ public function init_attribute_hooks() {
50
+ $attribute_taxonomies = wc_get_attribute_taxonomies();
51
+
52
+ if ( empty( $attribute_taxonomies ) ) {
53
+ return;
54
+ }
55
+
56
+ foreach ( $attribute_taxonomies as $tax ) {
57
+ add_action( 'pa_' . $tax->attribute_name . '_add_form_fields', array( $this, 'add_attribute_fields' ) );
58
+ add_action( 'pa_' . $tax->attribute_name . '_edit_form_fields', array( $this, 'edit_attribute_fields' ), 10, 2 );
59
+
60
+ add_filter( 'manage_edit-pa_' . $tax->attribute_name . '_columns', array( $this, 'add_attribute_columns' ) );
61
+ add_filter( 'manage_pa_' . $tax->attribute_name . '_custom_column', array( $this, 'add_attribute_column_content' ), 10, 3 );
62
+ }
63
+
64
+ add_action( 'created_term', array( $this, 'save_term_meta' ), 10, 2 );
65
+ add_action( 'edit_term', array( $this, 'save_term_meta' ), 10, 2 );
66
+ }
67
+
68
+ /**
69
+ * Load stylesheet and scripts in edit product attribute screen
70
+ */
71
+ public function enqueue_scripts() {
72
+ $screen = get_current_screen();
73
+ if ( strpos( $screen->id, 'edit-pa_' ) === false && strpos( $screen->id, 'product' ) === false ) {
74
+ return;
75
+ }
76
+
77
+ wp_enqueue_media();
78
+
79
+ wp_enqueue_style( 'tawcvs-admin', plugins_url( '/assets/css/admin.css', dirname( __FILE__ ) ), array( 'wp-color-picker' ), '20160615' );
80
+ wp_enqueue_script( 'tawcvs-admin', plugins_url( '/assets/js/admin.js', dirname( __FILE__ ) ), array( 'jquery', 'wp-color-picker', 'wp-util' ), '20170113', true );
81
+
82
+ wp_localize_script(
83
+ 'tawcvs-admin',
84
+ 'tawcvs',
85
+ array(
86
+ 'i18n' => array(
87
+ 'mediaTitle' => esc_html__( 'Choose an image', 'wcvs' ),
88
+ 'mediaButton' => esc_html__( 'Use image', 'wcvs' ),
89
+ ),
90
+ 'placeholder' => WC()->plugin_url() . '/assets/images/placeholder.png'
91
+ )
92
+ );
93
+ }
94
+
95
+ /**
96
+ * Create hook to add fields to add attribute term screen
97
+ *
98
+ * @param string $taxonomy
99
+ */
100
+ public function add_attribute_fields( $taxonomy ) {
101
+ $attr = TA_WCVS()->get_tax_attribute( $taxonomy );
102
+
103
+ do_action( 'tawcvs_product_attribute_field', $attr->attribute_type, '', 'add' );
104
+ }
105
+
106
+ /**
107
+ * Create hook to fields to edit attribute term screen
108
+ *
109
+ * @param object $term
110
+ * @param string $taxonomy
111
+ */
112
+ public function edit_attribute_fields( $term, $taxonomy ) {
113
+ $attr = TA_WCVS()->get_tax_attribute( $taxonomy );
114
+ $value = get_term_meta( $term->term_id, $attr->attribute_type, true );
115
+
116
+ do_action( 'tawcvs_product_attribute_field', $attr->attribute_type, $value, 'edit' );
117
+ }
118
+
119
+ /**
120
+ * Print HTML of custom fields on attribute term screens
121
+ *
122
+ * @param $type
123
+ * @param $value
124
+ * @param $form
125
+ */
126
+ public function attribute_fields( $type, $value, $form ) {
127
+ // Return if this is a default attribute type
128
+ if ( in_array( $type, array( 'select', 'text' ) ) ) {
129
+ return;
130
+ }
131
+
132
+ // Print the open tag of field container
133
+ printf(
134
+ '<%s class="form-field">%s<label for="term-%s">%s</label>%s',
135
+ 'edit' == $form ? 'tr' : 'div',
136
+ 'edit' == $form ? '<th>' : '',
137
+ esc_attr( $type ),
138
+ TA_WCVS()->types[$type],
139
+ 'edit' == $form ? '</th><td>' : ''
140
+ );
141
+
142
+ switch ( $type ) {
143
+ case 'image':
144
+ $image = $value ? wp_get_attachment_image_src( $value ) : '';
145
+ $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
146
+ ?>
147
+ <div class="tawcvs-term-image-thumbnail" style="float:left;margin-right:10px;">
148
+ <img src="<?php echo esc_url( $image ) ?>" width="60px" height="60px" />
149
+ </div>
150
+ <div style="line-height:60px;">
151
+ <input type="hidden" class="tawcvs-term-image" name="image" value="<?php echo esc_attr( $value ) ?>" />
152
+ <button type="button" class="tawcvs-upload-image-button button"><?php esc_html_e( 'Upload/Add image', 'wcvs' ); ?></button>
153
+ <button type="button" class="tawcvs-remove-image-button button <?php echo $value ? '' : 'hidden' ?>"><?php esc_html_e( 'Remove image', 'wcvs' ); ?></button>
154
+ </div>
155
+ <?php
156
+ break;
157
+
158
+ default:
159
+ ?>
160
+ <input type="text" id="term-<?php echo esc_attr( $type ) ?>" name="<?php echo esc_attr( $type ) ?>" value="<?php echo esc_attr( $value ) ?>" />
161
+ <?php
162
+ break;
163
+ }
164
+
165
+ // Print the close tag of field container
166
+ echo 'edit' == $form ? '</td></tr>' : '</div>';
167
+ }
168
+
169
+ /**
170
+ * Save term meta
171
+ *
172
+ * @param int $term_id
173
+ * @param int $tt_id
174
+ */
175
+ public function save_term_meta( $term_id, $tt_id ) {
176
+ foreach ( TA_WCVS()->types as $type => $label ) {
177
+ if ( isset( $_POST[$type] ) ) {
178
+ update_term_meta( $term_id, $type, $_POST[$type] );
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Add selector for extra attribute types
185
+ *
186
+ * @param $taxonomy
187
+ * @param $index
188
+ */
189
+ public function product_option_terms( $taxonomy, $index ) {
190
+ if ( ! array_key_exists( $taxonomy->attribute_type, TA_WCVS()->types ) ) {
191
+ return;
192
+ }
193
+
194
+ $taxonomy_name = wc_attribute_taxonomy_name( $taxonomy->attribute_name );
195
+ global $thepostid;
196
+ ?>
197
+
198
+ <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; ?>][]">
199
+ <?php
200
+
201
+ $all_terms = get_terms( $taxonomy_name, apply_filters( 'woocommerce_product_attribute_terms', array( 'orderby' => 'name', 'hide_empty' => false ) ) );
202
+ if ( $all_terms ) {
203
+ foreach ( $all_terms as $term ) {
204
+ echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( has_term( absint( $term->term_id ), $taxonomy_name, $thepostid ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
205
+ }
206
+ }
207
+ ?>
208
+ </select>
209
+ <button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'wcvs' ); ?></button>
210
+ <button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'wcvs' ); ?></button>
211
+ <button class="button fr plus tawcvs_add_new_attribute" data-type="<?php echo $taxonomy->attribute_type ?>"><?php esc_html_e( 'Add new', 'wcvs' ); ?></button>
212
+
213
+ <?php
214
+ }
215
+
216
+ /**
217
+ * Add thumbnail column to column list
218
+ *
219
+ * @param array $columns
220
+ *
221
+ * @return array
222
+ */
223
+ public function add_attribute_columns( $columns ) {
224
+ $new_columns = array();
225
+ $new_columns['cb'] = $columns['cb'];
226
+ $new_columns['thumb'] = '';
227
+ unset( $columns['cb'] );
228
+
229
+ return array_merge( $new_columns, $columns );
230
+ }
231
+
232
+ /**
233
+ * Render thumbnail HTML depend on attribute type
234
+ *
235
+ * @param $columns
236
+ * @param $column
237
+ * @param $term_id
238
+ */
239
+ public function add_attribute_column_content( $columns, $column, $term_id ) {
240
+ $attr = TA_WCVS()->get_tax_attribute( $_REQUEST['taxonomy'] );
241
+ $value = get_term_meta( $term_id, $attr->attribute_type, true );
242
+
243
+ switch ( $attr->attribute_type ) {
244
+ case 'color':
245
+ printf( '<div class="swatch-preview swatch-color" style="background-color:%s;"></div>', esc_attr( $value ) );
246
+ break;
247
+
248
+ case 'image':
249
+ $image = $value ? wp_get_attachment_image_src( $value ) : '';
250
+ $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
251
+ printf( '<img class="swatch-preview swatch-image" src="%s" width="44px" height="44px">', esc_url( $image ) );
252
+ break;
253
+
254
+ case 'label':
255
+ printf( '<div class="swatch-preview swatch-label">%s</div>', esc_html( $value ) );
256
+ break;
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Print HTML of modal at admin footer and add js templates
262
+ */
263
+ public function add_attribute_term_template() {
264
+ global $pagenow, $post;
265
+
266
+ if ( $pagenow != 'post.php' || ( isset( $post ) && get_post_type( $post->ID ) != 'product' ) ) {
267
+ return;
268
+ }
269
+ ?>
270
+
271
+ <div id="tawcvs-modal-container" class="tawcvs-modal-container">
272
+ <div class="tawcvs-modal">
273
+ <button type="button" class="button-link media-modal-close tawcvs-modal-close">
274
+ <span class="media-modal-icon"></span></button>
275
+ <div class="tawcvs-modal-header"><h2><?php esc_html_e( 'Add new term', 'wcvs' ) ?></h2></div>
276
+ <div class="tawcvs-modal-content">
277
+ <p class="tawcvs-term-name">
278
+ <label>
279
+ <?php esc_html_e( 'Name', 'wcvs' ) ?>
280
+ <input type="text" class="widefat tawcvs-input" name="name">
281
+ </label>
282
+ </p>
283
+ <p class="tawcvs-term-slug">
284
+ <label>
285
+ <?php esc_html_e( 'Slug', 'wcvs' ) ?>
286
+ <input type="text" class="widefat tawcvs-input" name="slug">
287
+ </label>
288
+ </p>
289
+ <div class="tawcvs-term-swatch">
290
+
291
+ </div>
292
+ <div class="hidden tawcvs-term-tax"></div>
293
+
294
+ <input type="hidden" class="tawcvs-input" name="nonce" value="<?php echo wp_create_nonce( '_tawcvs_create_attribute' ) ?>">
295
+ </div>
296
+ <div class="tawcvs-modal-footer">
297
+ <button class="button button-secondary tawcvs-modal-close"><?php esc_html_e( 'Cancel', 'wcvs' ) ?></button>
298
+ <button class="button button-primary tawcvs-new-attribute-submit"><?php esc_html_e( 'Add New', 'wcvs' ) ?></button>
299
+ <span class="message"></span>
300
+ <span class="spinner"></span>
301
+ </div>
302
+ </div>
303
+ <div class="tawcvs-modal-backdrop media-modal-backdrop"></div>
304
+ </div>
305
+
306
+ <script type="text/template" id="tmpl-tawcvs-input-color">
307
+
308
+ <label><?php esc_html_e( 'Color', 'wcvs' ) ?></label><br>
309
+ <input type="text" class="tawcvs-input tawcvs-input-color" name="swatch">
310
+
311
+ </script>
312
+
313
+ <script type="text/template" id="tmpl-tawcvs-input-image">
314
+
315
+ <label><?php esc_html_e( 'Image', 'wcvs' ) ?></label><br>
316
+ <div class="tawcvs-term-image-thumbnail" style="float:left;margin-right:10px;">
317
+ <img src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/placeholder.png' ) ?>" width="60px" height="60px" />
318
+ </div>
319
+ <div style="line-height:60px;">
320
+ <input type="hidden" class="tawcvs-input tawcvs-input-image tawcvs-term-image" name="swatch" value="" />
321
+ <button type="button" class="tawcvs-upload-image-button button"><?php esc_html_e( 'Upload/Add image', 'wcvs' ); ?></button>
322
+ <button type="button" class="tawcvs-remove-image-button button hidden"><?php esc_html_e( 'Remove image', 'wcvs' ); ?></button>
323
+ </div>
324
+
325
+ </script>
326
+
327
+ <script type="text/template" id="tmpl-tawcvs-input-label">
328
+
329
+ <label>
330
+ <?php esc_html_e( 'Label', 'wcvs' ) ?>
331
+ <input type="text" class="widefat tawcvs-input tawcvs-input-label" name="swatch">
332
+ </label>
333
+
334
+ </script>
335
+
336
+ <script type="text/template" id="tmpl-tawcvs-input-tax">
337
+
338
+ <input type="hidden" class="tawcvs-input" name="taxonomy" value="{{data.tax}}">
339
+ <input type="hidden" class="tawcvs-input" name="type" value="{{data.type}}">
340
+
341
+ </script>
342
+ <?php
343
+ }
344
+
345
+ /**
346
+ * Ajax function to handle add new attribute term
347
+ */
348
+ public function add_new_attribute_ajax() {
349
+ $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
350
+ $tax = isset( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : '';
351
+ $type = isset( $_POST['type'] ) ? $_POST['type'] : '';
352
+ $name = isset( $_POST['name'] ) ? $_POST['name'] : '';
353
+ $slug = isset( $_POST['slug'] ) ? $_POST['slug'] : '';
354
+ $swatch = isset( $_POST['swatch'] ) ? $_POST['swatch'] : '';
355
+
356
+ if ( ! wp_verify_nonce( $nonce, '_tawcvs_create_attribute' ) ) {
357
+ wp_send_json_error( esc_html__( 'Wrong request', 'wcvs' ) );
358
+ }
359
+
360
+ if ( empty( $name ) || empty( $swatch ) || empty( $tax ) || empty( $type ) ) {
361
+ wp_send_json_error( esc_html__( 'Not enough data', 'wcvs' ) );
362
+ }
363
+
364
+ if ( ! taxonomy_exists( $tax ) ) {
365
+ wp_send_json_error( esc_html__( 'Taxonomy is not exists', 'wcvs' ) );
366
+ }
367
+
368
+ if ( term_exists( $_POST['name'], $_POST['tax'] ) ) {
369
+ wp_send_json_error( esc_html__( 'This term is exists', 'wcvs' ) );
370
+ }
371
+
372
+ $term = wp_insert_term( $name, $tax, array( 'slug' => $slug ) );
373
+
374
+ if ( is_wp_error( $term ) ) {
375
+ wp_send_json_error( $term->get_error_message() );
376
+ } else {
377
+ $term = get_term_by( 'id', $term['term_id'], $tax );
378
+ update_term_meta( $term->term_id, $type, $swatch );
379
+ }
380
+
381
+ wp_send_json_success(
382
+ array(
383
+ 'msg' => esc_html__( 'Added successfully', 'wcvs' ),
384
+ 'id' => $term->term_id,
385
+ 'slug' => $term->slug,
386
+ 'name' => $term->name,
387
+ )
388
+ );
389
+ }
390
+ }
includes/class-frontend.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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', dirname( __FILE__ ) ), array(), '20160615' );
42
+ wp_enqueue_script( 'tawcvs-frontend', plugins_url( 'assets/js/frontend.js', dirname( __FILE__ ) ), array( 'jquery' ), '20160615', 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
+ if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
73
+ $attributes = $product->get_variation_attributes();
74
+ $options = $attributes[$attribute];
75
+ }
76
+
77
+ if ( array_key_exists( $attr->attribute_type, $swatch_types ) ) {
78
+ if ( ! empty( $options ) && $product && taxonomy_exists( $attribute ) ) {
79
+ // Get terms if this is a taxonomy - ordered. We need the names too.
80
+ $terms = wc_get_product_terms( $product->id, $attribute, array( 'fields' => 'all' ) );
81
+
82
+ foreach ( $terms as $term ) {
83
+ if ( in_array( $term->slug, $options ) ) {
84
+ $swatches .= apply_filters( 'tawcvs_swatch_html', '', $term, $attr, $args );
85
+ }
86
+ }
87
+ }
88
+
89
+ if ( ! empty( $swatches ) ) {
90
+ $class .= ' hidden';
91
+
92
+ $swatches = '<div class="tawcvs-swatches" data-attribute_name="attribute_' . esc_attr( $attribute ) . '">' . $swatches . '</div>';
93
+ $html = '<div class="' . esc_attr( $class ) . '">' . $html . '</div>' . $swatches;
94
+ }
95
+ }
96
+
97
+ return $html;
98
+ }
99
+
100
+ /**
101
+ * Print HTML of a single swatch
102
+ *
103
+ * @param $html
104
+ * @param $term
105
+ * @param $attr
106
+ * @param $args
107
+ *
108
+ * @return string
109
+ */
110
+ public function swatch_html( $html, $term, $attr, $args ) {
111
+ $selected = sanitize_title( $args['selected'] ) == $term->slug ? 'selected' : '';
112
+ $name = esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) );
113
+
114
+ switch ( $attr->attribute_type ) {
115
+ case 'color':
116
+ $color = get_term_meta( $term->term_id, 'color', true );
117
+ list( $r, $g, $b ) = sscanf( $color, "#%02x%02x%02x" );
118
+ $html = sprintf(
119
+ '<span class="swatch swatch-color swatch-%s %s" style="background-color:%s;color:%s;" title="%s" data-value="%s">%s</span>',
120
+ esc_attr( $term->slug ),
121
+ $selected,
122
+ esc_attr( $color ),
123
+ "rgba($r,$g,$b,0.5)",
124
+ esc_attr( $name ),
125
+ esc_attr( $term->slug ),
126
+ $name
127
+ );
128
+ break;
129
+
130
+ case 'image':
131
+ $image = get_term_meta( $term->term_id, 'image', true );
132
+ $image = $image ? wp_get_attachment_image_src( $image ) : '';
133
+ $image = $image ? $image[0] : WC()->plugin_url() . '/assets/images/placeholder.png';
134
+ $html = sprintf(
135
+ '<span class="swatch swatch-image swatch-%s %s" title="%s" data-value="%s"><img src="%s" alt="%s">%s</span>',
136
+ esc_attr( $term->slug ),
137
+ $selected,
138
+ esc_attr( $name ),
139
+ esc_attr( $term->slug ),
140
+ esc_url( $image ),
141
+ esc_attr( $name ),
142
+ esc_attr( $name )
143
+ );
144
+ break;
145
+
146
+ case 'label':
147
+ $label = get_term_meta( $term->term_id, 'label', true );
148
+ $label = $label ? $label : $name;
149
+ $html = sprintf(
150
+ '<span class="swatch swatch-label swatch-%s %s" title="%s" data-value="%s">%s</span>',
151
+ esc_attr( $term->slug ),
152
+ $selected,
153
+ esc_attr( $name ),
154
+ esc_attr( $term->slug ),
155
+ esc_html( $label )
156
+ );
157
+ break;
158
+ }
159
+
160
+ return $html;
161
+ }
162
+ }
languages/wcvs.pot ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #, fuzzy
2
+ msgid ""
3
+ msgstr ""
4
+ "Project-Id-Version: PACKAGE VERSION\n"
5
+ "Report-Msgid-Bugs-To: \n"
6
+ "POT-Creation-Date: 2017-01-14 10:16+0000\n"
7
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
+ "Language-Team: \n"
10
+ "Language: \n"
11
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
12
+ "MIME-Version: 1.0\n"
13
+ "Content-Type: text/plain; charset=UTF-8\n"
14
+ "Content-Transfer-Encoding: 8bit\n"
15
+ "X-Generator: Loco https://localise.biz/"
16
+
17
+ #: woocommerce-variation-swatches.php:57 includes/class-admin.php:303
18
+ msgid "Color"
19
+ msgstr ""
20
+
21
+ #: woocommerce-variation-swatches.php:58 includes/class-admin.php:310
22
+ msgid "Image"
23
+ msgstr ""
24
+
25
+ #: woocommerce-variation-swatches.php:59 includes/class-admin.php:325
26
+ msgid "Label"
27
+ msgstr ""
28
+
29
+ #: woocommerce-variation-swatches.php:161
30
+ msgid ""
31
+ "Soo Product Attribute Swatches is enabled but not effective. It requires "
32
+ "WooCommerce in order to work."
33
+ msgstr ""
34
+
35
+ #: includes/class-admin.php:87
36
+ msgid "Choose an image"
37
+ msgstr ""
38
+
39
+ #: includes/class-admin.php:88
40
+ msgid "Use image"
41
+ msgstr ""
42
+
43
+ #: includes/class-admin.php:147 includes/class-admin.php:316
44
+ msgid "Upload/Add image"
45
+ msgstr ""
46
+
47
+ #: includes/class-admin.php:148 includes/class-admin.php:317
48
+ msgid "Remove image"
49
+ msgstr ""
50
+
51
+ #: includes/class-admin.php:193
52
+ msgid "Select terms"
53
+ msgstr ""
54
+
55
+ #: includes/class-admin.php:204
56
+ msgid "Select all"
57
+ msgstr ""
58
+
59
+ #: includes/class-admin.php:205
60
+ msgid "Select none"
61
+ msgstr ""
62
+
63
+ #: includes/class-admin.php:206
64
+ msgid "Add new"
65
+ msgstr ""
66
+
67
+ #: includes/class-admin.php:270
68
+ msgid "Add new term"
69
+ msgstr ""
70
+
71
+ #: includes/class-admin.php:274
72
+ msgid "Name"
73
+ msgstr ""
74
+
75
+ #: includes/class-admin.php:280
76
+ msgid "Slug"
77
+ msgstr ""
78
+
79
+ #: includes/class-admin.php:292
80
+ msgid "Cancel"
81
+ msgstr ""
82
+
83
+ #: includes/class-admin.php:293
84
+ msgid "Add New"
85
+ msgstr ""
86
+
87
+ #: includes/class-admin.php:352
88
+ msgid "Wrong request"
89
+ msgstr ""
90
+
91
+ #: includes/class-admin.php:356
92
+ msgid "Not enough data"
93
+ msgstr ""
94
+
95
+ #: includes/class-admin.php:360
96
+ msgid "Taxonomy is not exists"
97
+ msgstr ""
98
+
99
+ #: includes/class-admin.php:364
100
+ msgid "This term is exists"
101
+ msgstr ""
102
+
103
+ #: includes/class-admin.php:378
104
+ msgid "Added successfully"
105
+ msgstr ""
106
+
107
+ #. Name of the plugin
108
+ msgid "WooCommerce Variation Swatches"
109
+ msgstr ""
110
+
111
+ #. Description of the plugin
112
+ msgid ""
113
+ "An extension of WooCommerce to make variation products be more beauty and "
114
+ "friendly with users."
115
+ msgstr ""
116
+
117
+ #. URI of the plugin
118
+ msgid "http://themealien.com/wordpress-plugin/woocommerce-variation-swatches"
119
+ msgstr ""
120
+
121
+ #. Author of the plugin
122
+ msgid "ThemeAlien"
123
+ msgstr ""
124
+
125
+ #. Author URI of the plugin
126
+ msgid "http://themealien.com/"
127
+ msgstr ""
readme.txt ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Variation Swatches for WooCommerce ===
2
+ Contributors: themealien
3
+ Tags: woocommerce, product attribute, product color, product size, variation swatches, variable products
4
+ Requires at least: 4.5
5
+ Tested up to: 4.7.2
6
+ Stable tag: 1.0.1
7
+ License: GPLv2 or later
8
+ License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ An extension of WooCommerce that make variable products be more beauty and friendly with customers.
11
+
12
+ == Description ==
13
+
14
+ 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 anything else in the better way which is not support by WooCommerce.
15
+ This plugin only add more options to show product variations with swatches. It doesn't touch the default dropdown style from WooCommerce.
16
+
17
+ With a friendly and easy-to-use interface, you can add default color, image or label to each attribute in the attribute management page. It can also help you pick the right style for quick-add attribute right inside the editing product page.
18
+
19
+ **Features provided with this plugin:**
20
+
21
+ * Completely integrate with WooCommerce plugin
22
+ * Work on variable product only
23
+ * Create attribute color swatches
24
+ * Create attribute image swatches
25
+ * Create attribute label/text swatches
26
+ * Manage attribute globally
27
+ * Create new attribute swatch in product editing page
28
+ * New options in WooCommerce Settings that help control swatches easier without touching code
29
+
30
+
31
+ == Installation ==
32
+
33
+ = Automatic installation =
34
+
35
+ Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser.
36
+
37
+ 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
38
+ 1. In the search field type "Variation Swatches for WooCommerce" and click Search Plugins.
39
+ 1. Once you’ve found it, you can install it by simply clicking Install Now button.
40
+
41
+ = Manual Installation =
42
+
43
+ 1. Download the Variation Swatches for WooCommerce plugin to your desktop.
44
+ 1. Extract the plugin folder to your desktop.
45
+ 1. Read through the "readme" file thoroughly to ensure you follow the installation instructions.
46
+ 1. With your FTP program, upload the Plugin folder to the wp-content/plugins folder in your WordPress directory online.
47
+ 1. Go to Plugins screen and find the "Variation Swatches for WooCommerce" in the list.
48
+ 1. Click Activate to activate it.
49
+
50
+ = Config attributes =
51
+
52
+ Even this plugin has been installed and activated on your site, variable products will still show dropdowns if you've not configured product attributes.
53
+
54
+ 1. Log in to your WordPress dashboard, navigate to the Products menu and click Attributes.
55
+ 1. Click to attribute name to edit an exists attribute or in the Add New Attribute form you will see the default Type selector.
56
+ 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.
57
+ 1. Select the suitable type for your attribute and click Save Change/Add attribute
58
+ 1. Go back to manage attributes screen. Click the cog icon on the right side of attribute to start editing terms.
59
+ 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.
60
+
61
+
62
+ == Frequently Asked Questions ==
63
+
64
+ = Will this plugin work with my theme? =
65
+ Yes, it will work with any theme, but may require some styling to make it match nicely.
66
+
67
+ == Screenshots ==
68
+
69
+ 1. Variations on frontend
70
+ 1. Add new attribute
71
+ 1. Edit Attribute
72
+ 1. Attribute color
73
+ 1. Attribute label
74
+ 1. Attribute image
75
+ 1. Add new attribute color when edit a product
76
+
77
+ == Changelog ==
78
+
79
+ = 1.0.1 =
80
+ * Add "swatches-support" class to the variations form
81
+
82
+ = 1.0.0 =
83
+ * Initial release.
uninstall.php ADDED
@@ -0,0 +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 );
variation-swatches-for-woocommerce.php ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: WooCommerce Variation Swatches
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 with users.
6
+ * Version: 1.0.1
7
+ * Author: ThemeAlien
8
+ * Author URI: http://themealien.com/
9
+ * Requires at least: 4.5
10
+ * Tested up to: 4.7.2
11
+ * License: GPLv2 or later
12
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
13
+ * Text Domain: tawvs
14
+ * Domain Path: /languages/
15
+ */
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit; // Exit if accessed directly.
18
+ }
19
+
20
+
21
+ /**
22
+ * The main plugin class
23
+ */
24
+ final class TA_WC_Variation_Swatches {
25
+ /**
26
+ * The single instance of the class
27
+ *
28
+ * @var TA_WC_Variation_Swatches
29
+ */
30
+ protected static $instance = null;
31
+
32
+ /**
33
+ * Extra attribute types
34
+ *
35
+ * @var array
36
+ */
37
+ public $types = array();
38
+
39
+ /**
40
+ * Main instance
41
+ *
42
+ * @return TA_WC_Variation_Swatches
43
+ */
44
+ public static function instance() {
45
+ if ( null == self::$instance ) {
46
+ self::$instance = new self();
47
+ }
48
+
49
+ return self::$instance;
50
+ }
51
+
52
+ /**
53
+ * Class constructor.
54
+ */
55
+ public function __construct() {
56
+ $this->types = array(
57
+ 'color' => esc_html__( 'Color', 'wcvs' ),
58
+ 'image' => esc_html__( 'Image', 'wcvs' ),
59
+ 'label' => esc_html__( 'Label', 'wcvs' ),
60
+ );
61
+
62
+ $this->includes();
63
+ $this->init_hooks();
64
+ }
65
+
66
+ /**
67
+ * Include required core files used in admin and on the frontend.
68
+ */
69
+ public function includes() {
70
+ require_once 'includes/class-admin.php';
71
+ require_once 'includes/class-frontend.php';
72
+ }
73
+
74
+ /**
75
+ * Initialize hooks
76
+ */
77
+ public function init_hooks() {
78
+ add_action( 'init', array( $this, 'load_textdomain' ) );
79
+
80
+ add_filter( 'product_attributes_type_selector', array( $this, 'add_attribute_types' ) );
81
+
82
+ if ( is_admin() ) {
83
+ add_action( 'init', array( 'TA_WC_Variation_Swatches_Admin', 'instance' ) );
84
+ } else {
85
+ add_action( 'init', array( 'TA_WC_Variation_Swatches_Frontend', 'instance' ) );
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Load plugin text domain
91
+ */
92
+ public function load_textdomain() {
93
+ load_plugin_textdomain( 'wcvs', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
94
+ }
95
+
96
+ /**
97
+ * Add extra attribute types
98
+ * Add color, image and label type
99
+ *
100
+ * @param array $types
101
+ *
102
+ * @return array
103
+ */
104
+ public function add_attribute_types( $types ) {
105
+ $types = array_merge( $types, $this->types );
106
+
107
+ return $types;
108
+ }
109
+
110
+ /**
111
+ * Get attribute's properties
112
+ *
113
+ * @param string $taxonomy
114
+ *
115
+ * @return object
116
+ */
117
+ public function get_tax_attribute( $taxonomy ) {
118
+ global $wpdb;
119
+
120
+ $attr = substr( $taxonomy, 3 );
121
+ $attr = $wpdb->get_row( "SELECT * FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = '$attr'" );
122
+
123
+ return $attr;
124
+ }
125
+
126
+ /**
127
+ * Instance of admin
128
+ *
129
+ * @return TA_WC_Variation_Swatches_Admin
130
+ */
131
+ public function admin() {
132
+ return TA_WC_Variation_Swatches_Admin::instance();
133
+ }
134
+
135
+ /**
136
+ * Instance of frontend
137
+ *
138
+ * @return TA_WC_Variation_Swatches_Frontend
139
+ */
140
+ public function frontend() {
141
+ return TA_WC_Variation_Swatches_Frontend::instance();
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Main instance of plugin
147
+ *
148
+ * @return TA_WC_Variation_Swatches
149
+ */
150
+ function TA_WCVS() {
151
+ return TA_WC_Variation_Swatches::instance();
152
+ }
153
+
154
+ /**
155
+ * Display notice in case of WooCommerce plugin is not activated
156
+ */
157
+ function ta_wc_variation_swatches_wc_notice() {
158
+ ?>
159
+
160
+ <div class="error">
161
+ <p><?php esc_html_e( 'Soo Product Attribute Swatches is enabled but not effective. It requires WooCommerce in order to work.', 'wcvs' ); ?></p>
162
+ </div>
163
+
164
+ <?php
165
+ }
166
+
167
+ /**
168
+ * Construct plugin when plugins loaded in order to make sure WooCommerce API is fully loaded
169
+ * Check if WooCommerce is not activated then show an admin notice
170
+ * or create the main instance of plugin
171
+ */
172
+ function ta_wc_variation_swatches_constructor() {
173
+ if ( ! function_exists( 'WC' ) ) {
174
+ add_action( 'admin_notices', 'ta_wc_variation_swatches_wc_notice' );
175
+ } else {
176
+ TA_WCVS();
177
+ }
178
+ }
179
+
180
+ add_action( 'plugins_loaded', 'ta_wc_variation_swatches_constructor' );
181
+