From 6eb7dcabf21566be53c81ad2c8f8f20f7fb46463 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Wed, 26 Apr 2017 10:18:41 -0400 Subject: [PATCH 001/127] Added WC_Meta_Data object It wraps an array, and tells if there were any changes before saving it --- includes/abstracts/abstract-wc-data.php | 18 ++++++---- includes/class-wc-meta-data.php | 48 +++++++++++++++++++++++++ woocommerce.php | 1 + 3 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 includes/class-wc-meta-data.php diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 28ddf87af65..3ff6096a1f4 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -320,11 +320,11 @@ abstract class WC_Data { foreach ( $data as $meta ) { $meta = (array) $meta; if ( isset( $meta['key'], $meta['value'], $meta['id'] ) ) { - $this->meta_data[] = (object) array( + $this->meta_data[] = new WC_Meta_Data( array( 'id' => $meta['id'], 'key' => $meta['key'], 'value' => $meta['value'], - ); + ) ); } } } @@ -343,10 +343,10 @@ abstract class WC_Data { if ( $unique ) { $this->delete_meta_data( $key ); } - $this->meta_data[] = (object) array( + $this->meta_data[] = new WC_Meta_Data( array( 'key' => $key, 'value' => $value, - ); + ) ); } /** @@ -448,11 +448,11 @@ abstract class WC_Data { $raw_meta_data = $this->data_store->read_meta( $this ); if ( $raw_meta_data ) { foreach ( $raw_meta_data as $meta ) { - $this->meta_data[] = (object) array( + $this->meta_data[] = new WC_Meta_Data( array( 'id' => (int) $meta->meta_id, 'key' => $meta->meta_key, 'value' => maybe_unserialize( $meta->meta_value ), - ); + ) ); } if ( ! empty( $this->cache_group ) ) { @@ -480,8 +480,12 @@ abstract class WC_Data { } elseif ( empty( $meta->id ) ) { $new_meta_id = $this->data_store->add_meta( $this, $meta ); $this->meta_data[ $array_key ]->id = $new_meta_id; + $meta->apply_changes(); } else { - $this->data_store->update_meta( $this, $meta ); + if ( $meta->get_changes() ) { + $this->data_store->update_meta( $this, $meta ); + $meta->apply_changes(); + } } } diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php new file mode 100644 index 00000000000..0f97e91cc23 --- /dev/null +++ b/includes/class-wc-meta-data.php @@ -0,0 +1,48 @@ + $value ) { + if ( in_array( $key, $this->properties ) ) { + $this->$key = $value; + } + } + $this->apply_changes(); + } + + /** + * Merge changes with data and clear. + * + */ + public function apply_changes() { + foreach ( $this->properties as $property ) { + $this->previous_value[ $property ] = $this->$property; + } + } + + /** + * Return data changes only. + * + * @return array + */ + public function get_changes() { + $changes = array(); + foreach ( array( 'id', 'key', 'value' ) as $property ) { + if ( array_key_exists( $property, $this->previous_value ) && + $this->previous_value[ $property ] !== $this->$property ) { + $changes[ $property ] = $this->$property; + } + } + + return $changes; + } + +} diff --git a/woocommerce.php b/woocommerce.php index f74c55a931a..9f526512683 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -306,6 +306,7 @@ final class WooCommerce { include_once( WC_ABSPATH . 'includes/class-wc-emails.php' ); include_once( WC_ABSPATH . 'includes/class-wc-data-exception.php' ); include_once( WC_ABSPATH . 'includes/class-wc-query.php' ); + include_once( WC_ABSPATH . 'incldues/class-wc-meta-data.php' ); // Meta data internal object include_once( WC_ABSPATH . 'includes/class-wc-order-factory.php' ); // Order factory include_once( WC_ABSPATH . 'includes/class-wc-product-factory.php' ); // Product factory include_once( WC_ABSPATH . 'includes/class-wc-payment-tokens.php' ); // Payment tokens controller From af65da6494be1f08499ee35a7c51742ae9df0b73 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Wed, 26 Apr 2017 19:39:19 -0400 Subject: [PATCH 002/127] Added doc-comments --- includes/class-wc-meta-data.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php index 0f97e91cc23..bc1c9d63789 100644 --- a/includes/class-wc-meta-data.php +++ b/includes/class-wc-meta-data.php @@ -1,5 +1,16 @@ $value ) { if ( in_array( $key, $this->properties ) ) { @@ -20,7 +36,6 @@ class WC_Meta_Data { /** * Merge changes with data and clear. - * */ public function apply_changes() { foreach ( $this->properties as $property ) { From 2e6dc17bd506091df5f75ba0773811d2c71091f2 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Thu, 27 Apr 2017 09:28:19 -0400 Subject: [PATCH 003/127] Improved update_meta_data function Also updated unit tests that was expecting the meta data as stdclass objects --- includes/abstracts/abstract-wc-data.php | 8 +++----- tests/unit-tests/crud/data.php | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 3ff6096a1f4..c55da870337 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -360,11 +360,9 @@ abstract class WC_Data { public function update_meta_data( $key, $value, $meta_id = '' ) { $this->maybe_read_meta_data(); if ( $array_key = $meta_id ? array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id ) : '' ) { - $this->meta_data[ current( $array_key ) ] = (object) array( - 'id' => $meta_id, - 'key' => $key, - 'value' => $value, - ); + $meta = $this->meta_data[ current( $array_key ) ]; + $meta->key = $key; + $meta->value = $value; } else { $this->add_meta_data( $key, $value, true ); } diff --git a/tests/unit-tests/crud/data.php b/tests/unit-tests/crud/data.php index 3c5349db1ee..9b2e73d968c 100644 --- a/tests/unit-tests/crud/data.php +++ b/tests/unit-tests/crud/data.php @@ -202,7 +202,10 @@ class WC_Tests_CRUD_Data extends WC_Unit_Test_Case { $object = new WC_Mock_WC_Data(); $object->set_meta_data( $metadata ); - $this->assertEquals( $metadata, $object->get_meta_data() ); + foreach ( $object->get_meta_data() as $id => $meta ) { + $this->assertEquals( get_object_vars( $metadata[ $id ] ), get_object_vars( $meta ) ); + } + } /** From de8b899d65416fd48cedaa390f44a735dcf54da9 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Thu, 27 Apr 2017 11:24:03 -0400 Subject: [PATCH 004/127] Fixed typo --- woocommerce.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/woocommerce.php b/woocommerce.php index 9f526512683..4426bcc1055 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -306,7 +306,7 @@ final class WooCommerce { include_once( WC_ABSPATH . 'includes/class-wc-emails.php' ); include_once( WC_ABSPATH . 'includes/class-wc-data-exception.php' ); include_once( WC_ABSPATH . 'includes/class-wc-query.php' ); - include_once( WC_ABSPATH . 'incldues/class-wc-meta-data.php' ); // Meta data internal object + include_once( WC_ABSPATH . 'includes/class-wc-meta-data.php' ); // Meta data internal object include_once( WC_ABSPATH . 'includes/class-wc-order-factory.php' ); // Order factory include_once( WC_ABSPATH . 'includes/class-wc-product-factory.php' ); // Product factory include_once( WC_ABSPATH . 'includes/class-wc-payment-tokens.php' ); // Payment tokens controller From dafc795d7c2404675b32e72e1a280c546b5e0124 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Tue, 23 May 2017 19:15:13 -0400 Subject: [PATCH 005/127] Abstracting the WC_Meta_Data Properties with __set/__get --- includes/class-wc-meta-data.php | 55 +++++++++++++++++++++++---------- tests/unit-tests/crud/data.php | 6 ++-- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php index bc1c9d63789..94473bc45ec 100644 --- a/includes/class-wc-meta-data.php +++ b/includes/class-wc-meta-data.php @@ -1,5 +1,9 @@ $value ) { - if ( in_array( $key, $this->properties ) ) { - $this->$key = $value; - } - } + $this->current_data = $meta; $this->apply_changes(); } @@ -38,9 +46,22 @@ class WC_Meta_Data { * Merge changes with data and clear. */ public function apply_changes() { - foreach ( $this->properties as $property ) { - $this->previous_value[ $property ] = $this->$property; + $this->data = $this->current_data; + } + + public function __set( $key, $value ) { + $this->current_data[ $key ] = $value; + } + + public function __isset( $key ) { + return array_key_exists( $key, $this->current_data ); + } + + public function __get( $key ) { + if ( array_key_exists( $key, $this->current_data )) { + return $this->current_data[ $key ]; } + return null; } /** @@ -49,11 +70,11 @@ class WC_Meta_Data { * @return array */ public function get_changes() { + $changes = array(); - foreach ( array( 'id', 'key', 'value' ) as $property ) { - if ( array_key_exists( $property, $this->previous_value ) && - $this->previous_value[ $property ] !== $this->$property ) { - $changes[ $property ] = $this->$property; + foreach ( $this->current_data as $id => $value) { + if ( ! array_key_exists( $id, $this->data ) || $value !== $this->data[ $id ] ) { + $changes[ $id ] = $value; } } diff --git a/tests/unit-tests/crud/data.php b/tests/unit-tests/crud/data.php index 034f316921f..a44e5198924 100644 --- a/tests/unit-tests/crud/data.php +++ b/tests/unit-tests/crud/data.php @@ -139,7 +139,7 @@ class WC_Tests_CRUD_Data extends WC_Unit_Test_Case { */ function test_get_meta_data_cache_invalidation() { $object = new WC_Order; - $object->add_meta_data( 'test_meta_key', 'val1', true ); + $object->add_meta_data( 'test_meta_key', array( 'val1' ), true ); $object->add_meta_data( 'test_multi_meta_key', 'val2' ); $object->add_meta_data( 'test_multi_meta_key', 'val3' ); $object->save(); @@ -242,7 +242,9 @@ class WC_Tests_CRUD_Data extends WC_Unit_Test_Case { $object->set_meta_data( $metadata ); foreach ( $object->get_meta_data() as $id => $meta ) { - $this->assertEquals( get_object_vars( $metadata[ $id ] ), get_object_vars( $meta ) ); + $this->assertEquals( $metadata[ $id ]->id, $meta->id); + $this->assertEquals( $metadata[ $id ]->key, $meta->key); + $this->assertEquals( $metadata[ $id ]->value, $meta->value); } } From addc80de152709901e0e7d9854b42b8e9898c721 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Wed, 31 May 2017 09:39:13 -0400 Subject: [PATCH 006/127] Fixed coding styles --- includes/class-wc-meta-data.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php index 94473bc45ec..cae977849ea 100644 --- a/includes/class-wc-meta-data.php +++ b/includes/class-wc-meta-data.php @@ -49,14 +49,34 @@ class WC_Meta_Data { $this->data = $this->current_data; } + /** + * Creates or updates a property in the metadata object. + * + * @param string $key + * @param mixed $value + * + */ public function __set( $key, $value ) { $this->current_data[ $key ] = $value; } + /** + * Checks if a given key exists in our data. This is called internally + * by `empty` and `isset`. + * + * @param string $key + */ public function __isset( $key ) { return array_key_exists( $key, $this->current_data ); } + /** + * Returns the value of any property. + * + * @param string $key + * + * @return mixed Property value or NULL if it does not exists + */ public function __get( $key ) { if ( array_key_exists( $key, $this->current_data )) { return $this->current_data[ $key ]; @@ -70,7 +90,6 @@ class WC_Meta_Data { * @return array */ public function get_changes() { - $changes = array(); foreach ( $this->current_data as $id => $value) { if ( ! array_key_exists( $id, $this->data ) || $value !== $this->data[ $id ] ) { From 0d1451b719f7207c70c8dd386f82243c332320f6 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Wed, 31 May 2017 09:40:29 -0400 Subject: [PATCH 007/127] Fixed coding styles --- tests/unit-tests/crud/data.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit-tests/crud/data.php b/tests/unit-tests/crud/data.php index a44e5198924..2004641fe6b 100644 --- a/tests/unit-tests/crud/data.php +++ b/tests/unit-tests/crud/data.php @@ -242,9 +242,9 @@ class WC_Tests_CRUD_Data extends WC_Unit_Test_Case { $object->set_meta_data( $metadata ); foreach ( $object->get_meta_data() as $id => $meta ) { - $this->assertEquals( $metadata[ $id ]->id, $meta->id); - $this->assertEquals( $metadata[ $id ]->key, $meta->key); - $this->assertEquals( $metadata[ $id ]->value, $meta->value); + $this->assertEquals( $metadata[ $id ]->id, $meta->id ); + $this->assertEquals( $metadata[ $id ]->key, $meta->key ); + $this->assertEquals( $metadata[ $id ]->value, $meta->value ); } } From 5997ffd4b1c9b7ab1c54149ad8275c402af8a9ce Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Thu, 1 Jun 2017 11:46:05 -0400 Subject: [PATCH 008/127] Fixed coding styles issues --- includes/abstracts/abstract-wc-data.php | 3 +-- includes/class-wc-meta-data.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index c89c179e170..22e645ff7d3 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -475,8 +475,7 @@ abstract class WC_Data { unset( $this->meta_data[ $array_key ] ); } } elseif ( empty( $meta->id ) ) { - $new_meta_id = $this->data_store->add_meta( $this, $meta ); - $this->meta_data[ $array_key ]->id = $new_meta_id; + $meta->id = $this->data_store->add_meta( $this, $meta ); $meta->apply_changes(); } else { if ( $meta->get_changes() ) { diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php index cae977849ea..2c45a8d2290 100644 --- a/includes/class-wc-meta-data.php +++ b/includes/class-wc-meta-data.php @@ -78,7 +78,7 @@ class WC_Meta_Data { * @return mixed Property value or NULL if it does not exists */ public function __get( $key ) { - if ( array_key_exists( $key, $this->current_data )) { + if ( array_key_exists( $key, $this->current_data ) ) { return $this->current_data[ $key ]; } return null; From 03a3ce9901998378165a25ab3979363dbb9e0bc5 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Thu, 1 Jun 2017 11:47:36 -0400 Subject: [PATCH 009/127] Fixed coding styles issues --- includes/class-wc-meta-data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php index 2c45a8d2290..41595e1055a 100644 --- a/includes/class-wc-meta-data.php +++ b/includes/class-wc-meta-data.php @@ -91,7 +91,7 @@ class WC_Meta_Data { */ public function get_changes() { $changes = array(); - foreach ( $this->current_data as $id => $value) { + foreach ( $this->current_data as $id => $value ) { if ( ! array_key_exists( $id, $this->data ) || $value !== $this->data[ $id ] ) { $changes[ $id ] = $value; } From b0f3b5a19da4a5a221d1f2dd99d74c0b2de71a39 Mon Sep 17 00:00:00 2001 From: Cesar Rodas Date: Thu, 1 Jun 2017 12:03:13 -0400 Subject: [PATCH 010/127] Added test_get_meta_data_cache_invalidation_array_to_scalar() unit tests --- tests/unit-tests/crud/data.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/unit-tests/crud/data.php b/tests/unit-tests/crud/data.php index 2004641fe6b..63a28b0db8f 100644 --- a/tests/unit-tests/crud/data.php +++ b/tests/unit-tests/crud/data.php @@ -138,6 +138,23 @@ class WC_Tests_CRUD_Data extends WC_Unit_Test_Case { * Tests the cache invalidation after an order is saved */ function test_get_meta_data_cache_invalidation() { + $object = new WC_Order; + $object->add_meta_data( 'test_meta_key', 'val1', true ); + $object->add_meta_data( 'test_multi_meta_key', 'val2' ); + $object->add_meta_data( 'test_multi_meta_key', 'val3' ); + $object->save(); + + $order = new WC_Order( $object->get_id() ); + $metas = $order->get_meta_data(); + $metas[0]->value = 'updated value'; + $order->save(); + + $order = new WC_Order( $object->get_id() ); + $metas = $order->get_meta_data(); + $this->assertEquals( 'updated value', $metas[0]->value ); + } + + function test_get_meta_data_cache_invalidation_array_to_scalar() { $object = new WC_Order; $object->add_meta_data( 'test_meta_key', array( 'val1' ), true ); $object->add_meta_data( 'test_multi_meta_key', 'val2' ); From efd42e6bc43ae321e8b883801faa419a3ad26ab7 Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Tue, 6 Jun 2017 19:10:24 +0200 Subject: [PATCH 011/127] Proof of concept to error when internal meta props are accessed directly --- includes/abstracts/abstract-wc-data.php | 17 +++++++++++++++++ includes/data-stores/class-wc-data-store-wp.php | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 976028f1333..4321c15f391 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -268,6 +268,18 @@ abstract class WC_Data { return array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) ); } + /** + * Validate meta key. + * + * @since 3.x + * @param string $key + */ + private function validate_meta_key( $key ) { + if ( $this->data_store && ! empty( $key ) && in_array( $key, $this->data_store->get_internal_meta_keys() ) ) { + throw new Exception( __( 'Meta properties should not be accessed directly. Use getters and setters.', 'woocommerce' ) ); + } + } + /** * Get Meta Data by Key. * @@ -278,6 +290,7 @@ abstract class WC_Data { * @return mixed */ public function get_meta( $key = '', $single = true, $context = 'view' ) { + $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); $meta_data = $this->get_meta_data(); $array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key ); @@ -307,6 +320,7 @@ abstract class WC_Data { * @return boolean */ public function meta_exists( $key = '' ) { + $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); $array_keys = wp_list_pluck( $this->get_meta_data(), 'key' ); return in_array( $key, $array_keys ); @@ -343,6 +357,7 @@ abstract class WC_Data { * @param bool $unique Should this be a unique key? */ public function add_meta_data( $key, $value, $unique = false ) { + $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); if ( $unique ) { $this->delete_meta_data( $key ); @@ -362,6 +377,7 @@ abstract class WC_Data { * @param int $meta_id */ public function update_meta_data( $key, $value, $meta_id = '' ) { + $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); if ( $array_key = $meta_id ? array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id ) : '' ) { $this->meta_data[ current( $array_key ) ] = (object) array( @@ -381,6 +397,7 @@ abstract class WC_Data { * @param string $key Meta key */ public function delete_meta_data( $key ) { + $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); if ( $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key ) ) { foreach ( $array_keys as $array_key ) { diff --git a/includes/data-stores/class-wc-data-store-wp.php b/includes/data-stores/class-wc-data-store-wp.php index cc0d53aa832..466df136dc3 100644 --- a/includes/data-stores/class-wc-data-store-wp.php +++ b/includes/data-stores/class-wc-data-store-wp.php @@ -417,4 +417,14 @@ class WC_Data_Store_WP { return $wp_query_args; } + + /** + * Return list of internal meta keys. + * + * @since 3.x + * @return array + */ + public function get_internal_meta_keys() { + return $this->internal_meta_keys; + } } From b5fd62274f93c326bb1632c51104dc2d1a1de99f Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Wed, 7 Jun 2017 12:30:03 +0200 Subject: [PATCH 012/127] Map the correct function and use notice instead of exception --- includes/abstracts/abstract-wc-data.php | 35 ++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 4321c15f391..93e051df30e 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -273,11 +273,15 @@ abstract class WC_Data { * * @since 3.x * @param string $key + * @return bool True if validation is successful, false otherwise */ private function validate_meta_key( $key ) { if ( $this->data_store && ! empty( $key ) && in_array( $key, $this->data_store->get_internal_meta_keys() ) ) { - throw new Exception( __( 'Meta properties should not be accessed directly. Use getters and setters.', 'woocommerce' ) ); + wc_doing_it_wrong( __FUNCTION__, __( 'Meta properties should not be accessed directly. Use getters and setters.', 'woocommerce' ), '3.x' ); + return false; } + + return true; } /** @@ -290,7 +294,14 @@ abstract class WC_Data { * @return mixed */ public function get_meta( $key = '', $single = true, $context = 'view' ) { - $this->validate_meta_key( $key ); + if ( ! $this->validate_meta_key() ) { + $function = 'get_' . $key; + + if ( is_callable( array( $this, $function ) ) ) { + return $this->{$function}(); + } + } + $this->maybe_read_meta_data(); $meta_data = $this->get_meta_data(); $array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key ); @@ -320,7 +331,6 @@ abstract class WC_Data { * @return boolean */ public function meta_exists( $key = '' ) { - $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); $array_keys = wp_list_pluck( $this->get_meta_data(), 'key' ); return in_array( $key, $array_keys ); @@ -357,7 +367,14 @@ abstract class WC_Data { * @param bool $unique Should this be a unique key? */ public function add_meta_data( $key, $value, $unique = false ) { - $this->validate_meta_key( $key ); + if ( ! $this->validate_meta_key() ) { + $function = 'set_' . $key; + + if ( is_callable( array( $this, $function ) ) ) { + return $this->{$function}( $value ); + } + } + $this->maybe_read_meta_data(); if ( $unique ) { $this->delete_meta_data( $key ); @@ -377,7 +394,14 @@ abstract class WC_Data { * @param int $meta_id */ public function update_meta_data( $key, $value, $meta_id = '' ) { - $this->validate_meta_key( $key ); + if ( ! $this->validate_meta_key() ) { + $function = 'set_' . $key; + + if ( is_callable( array( $this, $function ) ) ) { + return $this->{$function}( $value ); + } + } + $this->maybe_read_meta_data(); if ( $array_key = $meta_id ? array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id ) : '' ) { $this->meta_data[ current( $array_key ) ] = (object) array( @@ -397,7 +421,6 @@ abstract class WC_Data { * @param string $key Meta key */ public function delete_meta_data( $key ) { - $this->validate_meta_key( $key ); $this->maybe_read_meta_data(); if ( $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key ) ) { foreach ( $array_keys as $array_key ) { From 1584836fa9ea7c8f27254087353591abeeda39d2 Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Wed, 7 Jun 2017 12:31:42 +0200 Subject: [PATCH 013/127] Code style fixes --- includes/abstracts/abstract-wc-data.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 93e051df30e..8c9c6b8f924 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -403,7 +403,9 @@ abstract class WC_Data { } $this->maybe_read_meta_data(); - if ( $array_key = $meta_id ? array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id ) : '' ) { + $array_key = $meta_id ? array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id ) : ''; + + if ( $array_key ) { $this->meta_data[ current( $array_key ) ] = (object) array( 'id' => $meta_id, 'key' => $key, @@ -422,7 +424,9 @@ abstract class WC_Data { */ public function delete_meta_data( $key ) { $this->maybe_read_meta_data(); - if ( $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key ) ) { + $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key ); + + if ( $array_keys ) { foreach ( $array_keys as $array_key ) { $this->meta_data[ $array_key ]->value = null; } @@ -437,7 +441,9 @@ abstract class WC_Data { */ public function delete_meta_data_by_mid( $mid ) { $this->maybe_read_meta_data(); - if ( $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $mid ) ) { + $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $mid ); + + if ( $array_keys ) { foreach ( $array_keys as $array_key ) { $this->meta_data[ $array_key ]->value = null; } @@ -549,7 +555,7 @@ abstract class WC_Data { $this->data = $this->default_data; $this->changes = array(); $this->set_object_read( false ); - } + } /** * Set object read property. From 00847da73016e77f178acf72f3a2ab322148bc5d Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Wed, 7 Jun 2017 12:33:05 +0200 Subject: [PATCH 014/127] Fix --- includes/abstracts/abstract-wc-data.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 8c9c6b8f924..819e2d66c32 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -271,9 +271,9 @@ abstract class WC_Data { /** * Validate meta key. * - * @since 3.x - * @param string $key - * @return bool True if validation is successful, false otherwise + * @since 3.x + * @param string $key + * @return bool true if validation is successful, false otherwise */ private function validate_meta_key( $key ) { if ( $this->data_store && ! empty( $key ) && in_array( $key, $this->data_store->get_internal_meta_keys() ) ) { @@ -294,7 +294,7 @@ abstract class WC_Data { * @return mixed */ public function get_meta( $key = '', $single = true, $context = 'view' ) { - if ( ! $this->validate_meta_key() ) { + if ( ! $this->validate_meta_key( $key ) ) { $function = 'get_' . $key; if ( is_callable( array( $this, $function ) ) ) { @@ -367,7 +367,7 @@ abstract class WC_Data { * @param bool $unique Should this be a unique key? */ public function add_meta_data( $key, $value, $unique = false ) { - if ( ! $this->validate_meta_key() ) { + if ( ! $this->validate_meta_key( $key ) ) { $function = 'set_' . $key; if ( is_callable( array( $this, $function ) ) ) { @@ -394,7 +394,7 @@ abstract class WC_Data { * @param int $meta_id */ public function update_meta_data( $key, $value, $meta_id = '' ) { - if ( ! $this->validate_meta_key() ) { + if ( ! $this->validate_meta_key( $key ) ) { $function = 'set_' . $key; if ( is_callable( array( $this, $function ) ) ) { From 0271a9e2fe26f0bb6cc72f0ee1889184923e0578 Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Wed, 7 Jun 2017 16:20:09 +0200 Subject: [PATCH 015/127] Update version --- includes/abstracts/abstract-wc-data.php | 4 ++-- includes/data-stores/class-wc-data-store-wp.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 819e2d66c32..efb8d346f82 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -271,13 +271,13 @@ abstract class WC_Data { /** * Validate meta key. * - * @since 3.x + * @since 3.2.0 * @param string $key * @return bool true if validation is successful, false otherwise */ private function validate_meta_key( $key ) { if ( $this->data_store && ! empty( $key ) && in_array( $key, $this->data_store->get_internal_meta_keys() ) ) { - wc_doing_it_wrong( __FUNCTION__, __( 'Meta properties should not be accessed directly. Use getters and setters.', 'woocommerce' ), '3.x' ); + wc_doing_it_wrong( __FUNCTION__, __( 'Meta properties should not be accessed directly. Use getters and setters.', 'woocommerce' ), '3.2.0' ); return false; } diff --git a/includes/data-stores/class-wc-data-store-wp.php b/includes/data-stores/class-wc-data-store-wp.php index 466df136dc3..f58003eb80e 100644 --- a/includes/data-stores/class-wc-data-store-wp.php +++ b/includes/data-stores/class-wc-data-store-wp.php @@ -421,7 +421,7 @@ class WC_Data_Store_WP { /** * Return list of internal meta keys. * - * @since 3.x + * @since 3.2.0 * @return array */ public function get_internal_meta_keys() { From 68d512ae0103216cdaca968b80a6af2084b191d3 Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Thu, 8 Jun 2017 13:00:28 +0200 Subject: [PATCH 016/127] Address PR comments --- includes/abstracts/abstract-wc-data.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index efb8d346f82..db586bd4104 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -269,19 +269,20 @@ abstract class WC_Data { } /** - * Validate meta key. + * Check if the key is an internal one. * * @since 3.2.0 * @param string $key - * @return bool true if validation is successful, false otherwise + * @return bool true if it's an internal key, false otherwise */ - private function validate_meta_key( $key ) { + protected function is_internal_meta_key( $key ) { if ( $this->data_store && ! empty( $key ) && in_array( $key, $this->data_store->get_internal_meta_keys() ) ) { wc_doing_it_wrong( __FUNCTION__, __( 'Meta properties should not be accessed directly. Use getters and setters.', 'woocommerce' ), '3.2.0' ); - return false; + + return true; } - return true; + return false; } /** @@ -294,7 +295,7 @@ abstract class WC_Data { * @return mixed */ public function get_meta( $key = '', $single = true, $context = 'view' ) { - if ( ! $this->validate_meta_key( $key ) ) { + if ( $this->is_internal_meta_key( $key ) ) { $function = 'get_' . $key; if ( is_callable( array( $this, $function ) ) ) { @@ -367,7 +368,7 @@ abstract class WC_Data { * @param bool $unique Should this be a unique key? */ public function add_meta_data( $key, $value, $unique = false ) { - if ( ! $this->validate_meta_key( $key ) ) { + if ( $this->is_internal_meta_key( $key ) ) { $function = 'set_' . $key; if ( is_callable( array( $this, $function ) ) ) { @@ -394,7 +395,7 @@ abstract class WC_Data { * @param int $meta_id */ public function update_meta_data( $key, $value, $meta_id = '' ) { - if ( ! $this->validate_meta_key( $key ) ) { + if ( $this->is_internal_meta_key( $key ) ) { $function = 'set_' . $key; if ( is_callable( array( $this, $function ) ) ) { From 0f134d2b6f846e36b37112f3d75e806ed6d8eda4 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Wed, 12 Jul 2017 07:44:53 -0700 Subject: [PATCH 017/127] Begin product query --- includes/class-wc-product-query.php | 82 +++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 includes/class-wc-product-query.php diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php new file mode 100644 index 00000000000..25db7087051 --- /dev/null +++ b/includes/class-wc-product-query.php @@ -0,0 +1,82 @@ + 'publish', + 'type' => array( 'product', 'product_variation' ), + + + ) + ); + } + + /** + * Get products matching the current query vars. + * @return array of WC_Product objects + */ + public function get_products() { + $args = apply_filters( 'woocommerce_product_query_args', $this->get_query_vars() ); + $results = array();//WC_Data_Store::load( 'product' )->query( $args ); + return apply_filters( 'woocommerce_product_query', $results, $args ); + } +} From 753979ec49e2348b3926558028519cdf4c5f5a22 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Wed, 12 Jul 2017 13:58:39 -0700 Subject: [PATCH 018/127] WC_Product_Query --- includes/class-wc-product-query.php | 93 ++++++++++--------- .../class-wc-product-data-store-cpt.php | 93 +++++++++++++++++++ tests/unit-tests/product/query.php | 66 +++++++++++++ woocommerce.php | 1 + 4 files changed, 207 insertions(+), 46 deletions(-) create mode 100644 tests/unit-tests/product/query.php diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php index 25db7087051..b06c5fe6d09 100644 --- a/includes/class-wc-product-query.php +++ b/includes/class-wc-product-query.php @@ -13,47 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @category Class */ class WC_Product_Query extends WC_Object_Query { -/* - '_visibility', - '_sku', - '_price', - '_regular_price', - '_sale_price', - '_sale_price_dates_from', - '_sale_price_dates_to', - 'total_sales', - '_tax_status', - '_tax_class', - '_manage_stock', - '_stock', - '_stock_status', - '_backorders', - '_sold_individually', - '_weight', - '_length', - '_width', - '_height', - '_upsell_ids', - '_crosssell_ids', - '_purchase_note', - '_default_attributes', - '_product_attributes', - '_virtual', - '_downloadable', - '_featured', - '_downloadable_files', - '_wc_rating_count', - '_wc_average_rating', - '_wc_review_count', - '_variation_description', - '_thumbnail_id', - '_file_paths', - '_product_image_gallery', - '_product_version', - '_wp_old_slug', - '_edit_last', - '_edit_lock', -*/ + /** * Valid query vars for products. * @return array @@ -62,10 +22,51 @@ class WC_Product_Query extends WC_Object_Query { return array_merge( parent::get_default_query_vars(), array( - 'status' => 'publish', - 'type' => array( 'product', 'product_variation' ), - - + 'status' => 'publish', + 'type' => array( 'product', 'product_variation' ), + 'slug' => '', + 'date_created' => '', + 'date_modified' => '', + 'featured' => '', + 'catalog_visibility' => '', + 'description' => '', + 'short_description' => '', + 'sku' => '', + 'price' => '', + 'regular_price' => '', + 'sale_price' => '', + 'date_on_sale_from' => '', + 'date_on_sale_to' => '', + 'total_sales' => '', + 'tax_status' => '', + 'tax_class' => '', + 'manage_stock' => '', + 'stock_quantity' => '', + 'stock_status' => '', + 'backorders' => '', + 'sold_individually' => '', + 'weight' => '', + 'length' => '', + 'width' => '', + 'height' => '', + 'upsell_ids' => array(), + 'cross_sell_ids' => array(), + 'reviews_allowed' => '', + 'purchase_note' => '', + 'attributes' => array(), + 'default_attributes' => array(), + 'menu_order' => '', + 'virtual' => '', + 'downloadable' => '', + 'category_ids' => array(), + 'tag_ids' => array(), + 'shipping_class_id' => '', + 'image_id' => '', + 'download_limit' => '', + 'download_expiry' => '', + 'rating_counts' => array(), + 'average_rating' => '', + 'review_count' => '', ) ); } @@ -76,7 +77,7 @@ class WC_Product_Query extends WC_Object_Query { */ public function get_products() { $args = apply_filters( 'woocommerce_product_query_args', $this->get_query_vars() ); - $results = array();//WC_Data_Store::load( 'product' )->query( $args ); + $results = WC_Data_Store::load( 'product' )->query( $args ); return apply_filters( 'woocommerce_product_query', $results, $args ); } } diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 5fa2b9e0d4d..fab4b883a31 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1372,4 +1372,97 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da return false; } } + + + /** + * Get valid WP_Query args from a WC_Product_Query's query variables. + * + * @since 3.2.0 + * @param array $query_vars query vars from a WC_Product_Query + * @return array + */ + protected function get_wp_query_args( $query_vars ) { + + // Map query vars to ones that get_wp_query_args or WP_Query recognize. + $key_mapping = array( + 'status' => 'post_status', + 'page' => 'paged', + ); + + foreach ( $key_mapping as $query_key => $db_key ) { + if ( isset( $query_vars[ $query_key ] ) ) { + $query_vars[ $db_key ] = $query_vars[ $query_key ]; + unset( $query_vars[ $query_key ] ); + } + } + + $wp_query_args = parent::get_wp_query_args( $query_vars ); + + if ( ! isset( $wp_query_args['date_query'] ) ) { + $wp_query_args['date_query'] = array(); + } + if ( ! isset( $wp_query_args['meta_query'] ) ) { + $wp_query_args['meta_query'] = array(); + } + + $date_queries = array( + 'date_created' => 'post_date', + 'date_modified' => 'post_modified', + 'date_on_sale_from' => '_sale_price_dates_from', + 'date_on_sale_to' => '_sale_price_dates_to', + ); + foreach ( $date_queries as $query_var_key => $db_key ) { + if ( isset( $query_vars[ $query_var_key ] ) && '' !== $query_vars[ $query_var_key ] ) { + + // Remove any existing meta queries for the same keys to prevent conflicts. + $existing_queries = wp_list_pluck( $wp_query_args['meta_query'], 'key', true ); + foreach ( $existing_queries as $query_index => $query_contents ) { + unset( $wp_query_args['meta_query'][ $query_index ] ); + } + + $wp_query_args = $this->parse_date_for_wp_query( $query_vars[ $query_var_key ], $db_key, $wp_query_args ); + } + } + + if ( ! isset( $query_vars['paginate'] ) || ! $query_vars['paginate'] ) { + $wp_query_args['no_found_rows'] = true; + } + + return apply_filters( 'woocommerce_product_data_store_cpt_get_products_query', $wp_query_args, $query_vars, $this ); + } + + /** + * Query for Products matching specific criteria. + * + * @since 3.2.0 + * + * @param array $query_vars query vars from a WC_Product_Query + * + * @return array|object + */ + public function query( $query_vars ) { + $args = $this->get_wp_query_args( $query_vars ); + + if ( ! empty( $args['errors'] ) ) { + $query = (object) array( + 'posts' => array(), + 'found_posts' => 0, + 'max_num_pages' => 0, + ); + } else { + $query = new WP_Query( $args ); + } + + $products = ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) ? $query->posts : array_filter( array_map( 'wc_get_product', $query->posts ) ); + + if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) { + return (object) array( + 'products' => $products, + 'total' => $query->found_posts, + 'max_num_pages' => $query->max_num_pages, + ); + } + + return $products; + } } diff --git a/tests/unit-tests/product/query.php b/tests/unit-tests/product/query.php new file mode 100644 index 00000000000..f1d497bb43a --- /dev/null +++ b/tests/unit-tests/product/query.php @@ -0,0 +1,66 @@ +assertEquals( '', $query->get( 'weight' ) ); + $this->assertEquals( array( 'product', 'product_variation' ), $query->get( 'type' ) ); + } + + /** + * Test querying by product properties. + * + * @since 3.2 + */ + public function test_order_query_standard() { + $product1 = new WC_Product_Simple(); + $product1->set_sku( 'sku1' ); + $product1->set_regular_price( '10.00' ); + $product1->set_sale_price( '5.00' ); + $product1->save(); + + $product2 = new WC_Product_Variation(); + $product2->set_sku( 'sku2' ); + $product2->set_regular_price( '12.50' ); + $product2->set_sale_price( '5.00' ); + $product2->save(); + + // Just get some products. + $query = new WC_Product_Query(); + $results = $query->get_products(); + $this->assertEquals( 2, count( $results ) ); + + // Get products with a specific property.. + $query->set( 'sku', 'sku2' ); + $results = $query->get_products(); + $this->assertEquals( 1, count( $results ) ); + $this->assertEquals( $results[0]->get_id(), $product2->get_id() ); + + // Get products with two specific properties. + $query->set( 'regular_price', '12.50' ); + $results = $query->get_products(); + $this->assertEquals( 1, count( $results ) ); + $this->assertEquals( $results[0]->get_id(), $product2->get_id() ); + + // Get multiple products that have the same specific property. + $query = new WC_Product_Query(); + $query->set( 'sale_price', '5.00' ); + $results = $query->get_products(); + $this->assertEquals( 2, count( $results ) ); + + // Limit to one result. + $query->set( 'limit', 1 ); + $results = $query->get_products(); + $this->assertEquals( 1, count( $results ) ); + } +} diff --git a/woocommerce.php b/woocommerce.php index f46d0e3fce7..3dbafb11820 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -327,6 +327,7 @@ final class WooCommerce { include_once( WC_ABSPATH . 'includes/class-wc-order-factory.php' ); // Order factory include_once( WC_ABSPATH . 'includes/class-wc-order-query.php' ); // Order query include_once( WC_ABSPATH . 'includes/class-wc-product-factory.php' ); // Product factory + include_once( WC_ABSPATH . 'includes/class-wc-product-query.php' ); // Product query include_once( WC_ABSPATH . 'includes/class-wc-payment-tokens.php' ); // Payment tokens controller include_once( WC_ABSPATH . 'includes/class-wc-shipping-zone.php' ); include_once( WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-cc.php' ); // CC Payment Gateway From 7be2c7dc55ff07849ed7078d8a8dfab6487e5beb Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Wed, 12 Jul 2017 14:18:51 -0700 Subject: [PATCH 019/127] More tests --- tests/unit-tests/product/query.php | 86 +++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/tests/unit-tests/product/query.php b/tests/unit-tests/product/query.php index f1d497bb43a..ec70a930006 100644 --- a/tests/unit-tests/product/query.php +++ b/tests/unit-tests/product/query.php @@ -11,7 +11,7 @@ class WC_Tests_WC_Product_Query extends WC_Unit_Test_Case { * * @since 3.2 */ - public function test_order_query_new() { + public function test_product_query_new() { $query = new WC_Product_Query(); $this->assertEquals( '', $query->get( 'weight' ) ); $this->assertEquals( array( 'product', 'product_variation' ), $query->get( 'type' ) ); @@ -22,7 +22,7 @@ class WC_Tests_WC_Product_Query extends WC_Unit_Test_Case { * * @since 3.2 */ - public function test_order_query_standard() { + public function test_product_query_standard() { $product1 = new WC_Product_Simple(); $product1->set_sku( 'sku1' ); $product1->set_regular_price( '10.00' ); @@ -63,4 +63,86 @@ class WC_Tests_WC_Product_Query extends WC_Unit_Test_Case { $results = $query->get_products(); $this->assertEquals( 1, count( $results ) ); } + + + /** + * Test querying by product date properties for dates stored in metadata. + * + * @since 3.2 + */ + public function test_product_query_meta_date_queries() { + $now = current_time( 'mysql', true ); + $now_stamp = strtotime( $now ); + $now_date = date( 'Y-m-d', $now_stamp ); + $past_stamp = $now_stamp - DAY_IN_SECONDS; + $past = date( 'Y-m-d', $past_stamp ); + $future_stamp = $now_stamp + DAY_IN_SECONDS; + $future = date( 'Y-m-d', $future_stamp ); + + $product = new WC_Product_Simple(); + $product->set_date_on_sale_from( $now_stamp ); + $product->save(); + + // Check WC_DateTime support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => $product->get_date_on_sale_from(), + ) ); + $products = $query->get_products(); + $this->assertEquals( 1, count( $products ) ); + + // Check date support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => $now_date, + ) ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', $past ); + $this->assertEquals( 0, count( $query->get_products() ) ); + + // Check timestamp support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => $product->get_date_on_sale_from()->getTimestamp(), + ) ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', $future_stamp ); + $this->assertEquals( 0, count( $query->get_products() ) ); + + // Check comparison support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => '>' . $past, + ) ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', '<' . $past ); + $this->assertEquals( 0, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', '>=' . $now_date ); + $this->assertEquals( 1, count( $query->get_products() ) ); + + // Check timestamp comparison support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => '<' . $future_stamp, + ) ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', '<' . $past_stamp ); + $this->assertEquals( 0, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', '>=' . $now_stamp ); + + // Check date range support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => $past . '...' . $future, + ) ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', $now_date . '...' . $future ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', $future . '...' . $now_date ); + $this->assertEquals( 0, count( $query->get_products() ) ); + + // Check timestamp range support. + $query = new WC_Product_Query( array( + 'date_on_sale_from' => $past_stamp . '...' . $future_stamp, + ) ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', $now_stamp . '...' . $future_stamp ); + $this->assertEquals( 1, count( $query->get_products() ) ); + $query->set( 'date_on_sale_from', $future_stamp . '...' . $now_stamp ); + $this->assertEquals( 0, count( $query->get_products() ) ); + } } From bf9a7381dc8099042726a195680f7a3587196102 Mon Sep 17 00:00:00 2001 From: Ninos Ego Date: Thu, 13 Jul 2017 13:15:58 +0200 Subject: [PATCH 020/127] Coding improvements for datepicker range --- assets/js/admin/meta-boxes-product-variation.js | 4 ++-- assets/js/admin/meta-boxes-product.js | 9 ++++----- assets/js/admin/reports.js | 5 ++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/assets/js/admin/meta-boxes-product-variation.js b/assets/js/admin/meta-boxes-product-variation.js index bc3e644583e..17819a83276 100644 --- a/assets/js/admin/meta-boxes-product-variation.js +++ b/assets/js/admin/meta-boxes-product-variation.js @@ -123,10 +123,10 @@ jQuery( function( $ ) { dateFormat: 'yy-mm-dd', numberOfMonths: 1, showButtonPanel: true, - onSelect: function( selectedDate, instance ) { + onSelect: function() { var option = $( this ).is( '.sale_price_dates_from' ) ? 'minDate' : 'maxDate', dates = $( this ).closest( '.sale_price_dates_fields' ).find( 'input' ), - date = $.datepicker.parseDate( instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings ); + date = $( this ).datepicker( 'getDate' ); dates.not( this ).datepicker( 'option', option, date ); $( this ).change(); diff --git a/assets/js/admin/meta-boxes-product.js b/assets/js/admin/meta-boxes-product.js index f236cbb6dfc..31a6882a76a 100644 --- a/assets/js/admin/meta-boxes-product.js +++ b/assets/js/admin/meta-boxes-product.js @@ -244,11 +244,10 @@ jQuery( function( $ ) { dateFormat: 'yy-mm-dd', numberOfMonths: 1, showButtonPanel: true, - onSelect: function( selectedDate ) { - var option = $( this ).next().is('.hasDatepicker') ? 'minDate' : 'maxDate', - instance = $( this ).data( 'datepicker' ), - dates = $( this ).closest( '.sale_price_dates_fields' ).find( 'input' ), - date = $.datepicker.parseDate( instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings ); + onSelect: function() { + var option = $( this ).next().is('.hasDatepicker') ? 'minDate' : 'maxDate', + dates = $( this ).closest( '.sale_price_dates_fields' ).find( 'input' ), + date = $( this ).datepicker( 'getDate' ); dates.not( this ).datepicker( 'option', option, date ); $( this ).change(); diff --git a/assets/js/admin/reports.js b/assets/js/admin/reports.js index 0a3d1e8e0b5..6005d15fb3f 100644 --- a/assets/js/admin/reports.js +++ b/assets/js/admin/reports.js @@ -115,10 +115,9 @@ jQuery(function( $ ) { showButtonPanel: true, showOn: 'focus', buttonImageOnly: true, - onSelect: function( selectedDate ) { + onSelect: function() { var option = $( this ).is( '.from' ) ? 'minDate' : 'maxDate', - instance = $( this ).data( 'datepicker' ), - date = $.datepicker.parseDate( instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings ); + date = $( this ).datepicker( 'getDate' ); dates.not( this ).datepicker( 'option', option, date ); } From ac4d2db43aaee4362367f1a91e4de2d71eda3c67 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jul 2017 14:50:30 +0100 Subject: [PATCH 021/127] Improve tracking page validation Ensures error messages are vague but reflect the posted data. Closes #15986 --- .../class-wc-shortcode-order-tracking.php | 28 ++++++++----------- templates/order/form-tracking.php | 4 +-- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/includes/shortcodes/class-wc-shortcode-order-tracking.php b/includes/shortcodes/class-wc-shortcode-order-tracking.php index b12d84743e6..145807f49c9 100644 --- a/includes/shortcodes/class-wc-shortcode-order-tracking.php +++ b/includes/shortcodes/class-wc-shortcode-order-tracking.php @@ -32,7 +32,6 @@ class WC_Shortcode_Order_Tracking { * @param array $atts */ public static function output( $atts ) { - // Check cart class is loaded or abort if ( is_null( WC()->cart ) ) { return; @@ -40,31 +39,26 @@ class WC_Shortcode_Order_Tracking { extract( shortcode_atts( array(), $atts, 'woocommerce_order_tracking' ) ); - global $post; + if ( isset( $_REQUEST['orderid'], $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-order_tracking' ) ) { - if ( ! empty( $_REQUEST['orderid'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-order_tracking' ) ) { - - $order_id = empty( $_REQUEST['orderid'] ) ? 0 : esc_attr( $_REQUEST['orderid'] ); - $order_email = empty( $_REQUEST['order_email'] ) ? '' : esc_attr( $_REQUEST['order_email'] ); + $order_id = empty( $_REQUEST['orderid'] ) ? 0 : wc_clean( ltrim( $_REQUEST['orderid'], '#' ) ); + $order_email = empty( $_REQUEST['order_email'] ) ? '' : sanitize_email( $_REQUEST['order_email'] ); if ( ! $order_id ) { wc_add_notice( __( 'Please enter a valid order ID', 'woocommerce' ), 'error' ); } elseif ( ! $order_email ) { - wc_add_notice( __( 'Please enter a valid order email', 'woocommerce' ), 'error' ); + wc_add_notice( __( 'Please enter a valid email address', 'woocommerce' ), 'error' ); } else { $order = wc_get_order( apply_filters( 'woocommerce_shortcode_order_tracking_order_id', $order_id ) ); - if ( $order && $order->get_id() && $order_email ) { - if ( strtolower( $order->get_billing_email() ) == strtolower( $order_email ) ) { - do_action( 'woocommerce_track_order', $order->get_id() ); - wc_get_template( 'order/tracking.php', array( - 'order' => $order, - ) ); - - return; - } + if ( $order && $order->get_id() && strtolower( $order->get_billing_email() ) === strtolower( $order_email ) ) { + do_action( 'woocommerce_track_order', $order->get_id() ); + wc_get_template( 'order/tracking.php', array( + 'order' => $order, + ) ); + return; } else { - wc_add_notice( __( 'Sorry, we could not find that order ID in our database.', 'woocommerce' ), 'error' ); + wc_add_notice( __( 'Sorry, the order could not be found. Please contact us if you are having difficulty finding your order details.', 'woocommerce' ), 'error' ); } } } diff --git a/templates/order/form-tracking.php b/templates/order/form-tracking.php index a390c6e537b..72c6e3b28fe 100644 --- a/templates/order/form-tracking.php +++ b/templates/order/form-tracking.php @@ -28,8 +28,8 @@ global $post;

-

-

+

+

From f66198c37dcdaa9414fd507866506e1777beb00d Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Fri, 14 Jul 2017 09:50:20 -0700 Subject: [PATCH 022/127] Initial working wc_get_products --- includes/class-wc-product-query.php | 11 ++- .../class-wc-product-data-store-cpt.php | 69 +++++++++++++++++++ includes/wc-product-functions.php | 5 +- tests/unit-tests/product/query.php | 7 +- 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php index b06c5fe6d09..c8ed55f5355 100644 --- a/includes/class-wc-product-query.php +++ b/includes/class-wc-product-query.php @@ -22,8 +22,10 @@ class WC_Product_Query extends WC_Object_Query { return array_merge( parent::get_default_query_vars(), array( - 'status' => 'publish', - 'type' => array( 'product', 'product_variation' ), + 'status' => array( 'draft', 'pending', 'private', 'publish' ), + 'type' => array_merge( array_keys( wc_get_product_types() ) ), + 'limit' => get_option( 'posts_per_page' ), + 'include' => array(), 'slug' => '', 'date_created' => '', 'date_modified' => '', @@ -58,9 +60,12 @@ class WC_Product_Query extends WC_Object_Query { 'menu_order' => '', 'virtual' => '', 'downloadable' => '', + 'category' => array(), 'category_ids' => array(), 'tag_ids' => array(), - 'shipping_class_id' => '', + 'tag' => array(), + 'shipping_class_id' => array(), + 'shipping_class' => array(), 'image_id' => '', 'download_limit' => '', 'download_expiry' => '', diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index fab4b883a31..164f5684a4d 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1396,8 +1396,25 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da } } + // SKU needs special handling because it works with partial matches. + // Don't auto-generate meta query args for it. + $sku_query = false; + if ( isset( $query_vars['sku'] ) ) { + $sku_query = $query_vars['sku']; + unset( $query_vars['sku'] ); + } + $wp_query_args = parent::get_wp_query_args( $query_vars ); + // Add the special SKU query if needed. + if ( $sku_query ) { + $wp_query_args['meta_query'][] = array( + 'key' => '_sku', + 'value' => $sku_query, + 'compare' => 'LIKE', + ); + } + if ( ! isset( $wp_query_args['date_query'] ) ) { $wp_query_args['date_query'] = array(); } @@ -1405,6 +1422,58 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da $wp_query_args['meta_query'] = array(); } + // Handle product types. + if ( 'variation' === $query_vars['type'] ) { + $wp_query_args['post_type'] = 'product_variation'; + } elseif ( is_array( $query_vars['type'] ) && in_array( 'variation', $query_vars['type'] ) ) { + $wp_query_args['post_type'] = array( 'product_variation', 'product' ); + $wp_query_args['tax_query'][] = array( + 'relation' => 'OR', + array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $query_vars['type'], + ), + array( + 'taxonomy' => 'product_type', + 'field' => 'id', + 'operator' => 'NOT EXISTS', + ), + ); + } else { + $wp_query_args['post_type'] = 'product'; + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $query_vars['type'], + ); + } + + if ( ! empty( $query_vars['category'] ) ) { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_cat', + 'field' => 'slug', + 'terms' => $query_vars['category'], + ); + } + + if ( ! empty( $query_vars['tag'] ) ) { + unset( $wp_query_args['tag'] ); + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_tag', + 'field' => 'slug', + 'terms' => $query_vars['tag'], + ); + } + + if ( ! empty( $query_vars['shipping_class'] ) ) { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_shipping_class', + 'field' => 'slug', + 'terms' => $query_vars['shipping_class'], + ); + } + $date_queries = array( 'date_created' => 'post_date', 'date_modified' => 'post_modified', diff --git a/includes/wc-product-functions.php b/includes/wc-product-functions.php index fd9b973c7d6..e9b9d74b0dc 100644 --- a/includes/wc-product-functions.php +++ b/includes/wc-product-functions.php @@ -85,7 +85,10 @@ function wc_get_products( $args ) { } } - return WC_Data_Store::load( 'product' )->get_products( $args ); + $query = new WC_Product_Query( $args ); + return $query->get_products(); + + //return WC_Data_Store::load( 'product' )->get_products( $args ); } /** diff --git a/tests/unit-tests/product/query.php b/tests/unit-tests/product/query.php index ec70a930006..8d9da11f1a8 100644 --- a/tests/unit-tests/product/query.php +++ b/tests/unit-tests/product/query.php @@ -14,7 +14,9 @@ class WC_Tests_WC_Product_Query extends WC_Unit_Test_Case { public function test_product_query_new() { $query = new WC_Product_Query(); $this->assertEquals( '', $query->get( 'weight' ) ); - $this->assertEquals( array( 'product', 'product_variation' ), $query->get( 'type' ) ); + $types = $query->get( 'type' ); + sort( $types ); + $this->assertEquals( array( 'external', 'grouped', 'simple', 'variable' ), $types ); } /** @@ -29,7 +31,7 @@ class WC_Tests_WC_Product_Query extends WC_Unit_Test_Case { $product1->set_sale_price( '5.00' ); $product1->save(); - $product2 = new WC_Product_Variation(); + $product2 = new WC_Product_Grouped(); $product2->set_sku( 'sku2' ); $product2->set_regular_price( '12.50' ); $product2->set_sale_price( '5.00' ); @@ -64,7 +66,6 @@ class WC_Tests_WC_Product_Query extends WC_Unit_Test_Case { $this->assertEquals( 1, count( $results ) ); } - /** * Test querying by product date properties for dates stored in metadata. * From b04534bb853f447f71fd55cf7df2f856d0fb416f Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Fri, 14 Jul 2017 10:01:25 -0700 Subject: [PATCH 023/127] Hook everything up to wc_product_query --- includes/class-wc-product-query.php | 3 - .../class-wc-product-data-store-cpt.php | 130 ++---------------- 2 files changed, 10 insertions(+), 123 deletions(-) diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php index c8ed55f5355..935e962bb4d 100644 --- a/includes/class-wc-product-query.php +++ b/includes/class-wc-product-query.php @@ -61,10 +61,7 @@ class WC_Product_Query extends WC_Object_Query { 'virtual' => '', 'downloadable' => '', 'category' => array(), - 'category_ids' => array(), - 'tag_ids' => array(), 'tag' => array(), - 'shipping_class_id' => array(), 'shipping_class' => array(), 'image_id' => '', 'download_limit' => '', diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 164f5684a4d..0513566a35b 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1168,124 +1168,8 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da * @return array|object */ public function get_products( $args = array() ) { - /** - * Generate WP_Query args. - */ - $wp_query_args = array( - 'post_status' => $args['status'], - 'posts_per_page' => $args['limit'], - 'meta_query' => array(), - 'orderby' => $args['orderby'], - 'order' => $args['order'], - 'tax_query' => array(), - ); - - if ( 'variation' === $args['type'] ) { - $wp_query_args['post_type'] = 'product_variation'; - } elseif ( is_array( $args['type'] ) && in_array( 'variation', $args['type'] ) ) { - $wp_query_args['post_type'] = array( 'product_variation', 'product' ); - $wp_query_args['tax_query'][] = array( - 'relation' => 'OR', - array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $args['type'], - ), - array( - 'taxonomy' => 'product_type', - 'field' => 'id', - 'operator' => 'NOT EXISTS', - ), - ); - } else { - $wp_query_args['post_type'] = 'product'; - $wp_query_args['tax_query'][] = array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $args['type'], - ); - } - - // Do not load unnecessary post data if the user only wants IDs. - if ( 'ids' === $args['return'] ) { - $wp_query_args['fields'] = 'ids'; - } - - if ( ! empty( $args['sku'] ) ) { - $wp_query_args['meta_query'][] = array( - 'key' => '_sku', - 'value' => $args['sku'], - 'compare' => 'LIKE', - ); - } - - if ( ! empty( $args['category'] ) ) { - $wp_query_args['tax_query'][] = array( - 'taxonomy' => 'product_cat', - 'field' => 'slug', - 'terms' => $args['category'], - ); - } - - if ( ! empty( $args['tag'] ) ) { - $wp_query_args['tax_query'][] = array( - 'taxonomy' => 'product_tag', - 'field' => 'slug', - 'terms' => $args['tag'], - ); - } - - if ( ! empty( $args['shipping_class'] ) ) { - $wp_query_args['tax_query'][] = array( - 'taxonomy' => 'product_shipping_class', - 'field' => 'slug', - 'terms' => $args['shipping_class'], - ); - } - - if ( ! is_null( $args['parent'] ) ) { - $wp_query_args['post_parent'] = absint( $args['parent'] ); - } - - if ( ! is_null( $args['offset'] ) ) { - $wp_query_args['offset'] = absint( $args['offset'] ); - } else { - $wp_query_args['paged'] = absint( $args['page'] ); - } - - if ( ! empty( $args['include'] ) ) { - $wp_query_args['post__in'] = array_map( 'absint', $args['include'] ); - } - - if ( ! empty( $args['exclude'] ) ) { - $wp_query_args['post__not_in'] = array_map( 'absint', $args['exclude'] ); - } - - if ( ! $args['paginate'] ) { - $wp_query_args['no_found_rows'] = true; - } - - // Get results. - $products = new WP_Query( $wp_query_args ); - - if ( 'objects' === $args['return'] ) { - // Prime caches before grabbing objects. - update_post_caches( $products->posts, array( 'product', 'product_variation' ) ); - - $return = array_filter( array_map( 'wc_get_product', $products->posts ) ); - } else { - $return = $products->posts; - } - - if ( $args['paginate'] ) { - return (object) array( - 'products' => $return, - 'total' => $products->found_posts, - 'max_num_pages' => $products->max_num_pages, - ); - } else { - return $return; - } + $query = new WC_Product_Query( $args ); + return $query->get_products(); } /** @@ -1385,8 +1269,9 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da // Map query vars to ones that get_wp_query_args or WP_Query recognize. $key_mapping = array( - 'status' => 'post_status', - 'page' => 'paged', + 'status' => 'post_status', + 'page' => 'paged', + 'include' => 'post__in', ); foreach ( $key_mapping as $query_key => $db_key ) { @@ -1522,6 +1407,11 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da $query = new WP_Query( $args ); } + if ( isset( $query_vars['return'] ) && 'objects' === $query_vars['return'] && ! empty( $query->posts ) ) { + // Prime caches before grabbing objects. + update_post_caches( $products->posts, array( 'product', 'product_variation' ) ); + } + $products = ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) ? $query->posts : array_filter( array_map( 'wc_get_product', $query->posts ) ); if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) { From 96bc5e6f9556d6e0377d8ae0a9f44ec1701a8e7c Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Fri, 14 Jul 2017 10:07:18 -0700 Subject: [PATCH 024/127] cleanup --- includes/wc-product-functions.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/includes/wc-product-functions.php b/includes/wc-product-functions.php index e9b9d74b0dc..8c8dd5013c2 100644 --- a/includes/wc-product-functions.php +++ b/includes/wc-product-functions.php @@ -87,8 +87,6 @@ function wc_get_products( $args ) { $query = new WC_Product_Query( $args ); return $query->get_products(); - - //return WC_Data_Store::load( 'product' )->get_products( $args ); } /** From 8c8684b8aa4b8e48f20d42ecd667c837252295f4 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Fri, 14 Jul 2017 10:10:37 -0700 Subject: [PATCH 025/127] Move meta query init above sku query --- .../class-wc-product-data-store-cpt.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 0513566a35b..872e7c2614f 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1291,6 +1291,13 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da $wp_query_args = parent::get_wp_query_args( $query_vars ); + if ( ! isset( $wp_query_args['date_query'] ) ) { + $wp_query_args['date_query'] = array(); + } + if ( ! isset( $wp_query_args['meta_query'] ) ) { + $wp_query_args['meta_query'] = array(); + } + // Add the special SKU query if needed. if ( $sku_query ) { $wp_query_args['meta_query'][] = array( @@ -1300,13 +1307,6 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da ); } - if ( ! isset( $wp_query_args['date_query'] ) ) { - $wp_query_args['date_query'] = array(); - } - if ( ! isset( $wp_query_args['meta_query'] ) ) { - $wp_query_args['meta_query'] = array(); - } - // Handle product types. if ( 'variation' === $query_vars['type'] ) { $wp_query_args['post_type'] = 'product_variation'; From 60bbb41be8e7834324ece6632c5abc602874008a Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Tue, 18 Jul 2017 15:03:26 +0100 Subject: [PATCH 026/127] Introduce `wc_get_account_orders_actions` function to reduce the amount of logic inside the account orders template files. --- includes/wc-account-functions.php | 39 +++++++++++++++++++++++++++++++ templates/myaccount/my-orders.php | 33 +++++--------------------- templates/myaccount/orders.php | 35 ++++++--------------------- 3 files changed, 52 insertions(+), 55 deletions(-) diff --git a/includes/wc-account-functions.php b/includes/wc-account-functions.php index a05f5acc872..54796c53d10 100644 --- a/includes/wc-account-functions.php +++ b/includes/wc-account-functions.php @@ -240,6 +240,45 @@ function wc_get_account_payment_methods_types() { ) ); } +/** + * Get account orders actions. + * + * @since 3.2.0 + * @param int|WC_Order $order + * @return array + */ +function wc_get_account_orders_actions( $order ) { + if ( ! is_object( $order ) ) { + $order_id = absint( $order ); + $order = wc_get_order( $order_id ); + } + + $actions = array( + 'pay' => array( + 'url' => $order->get_checkout_payment_url(), + 'name' => __( 'Pay', 'woocommerce' ), + ), + 'view' => array( + 'url' => $order->get_view_order_url(), + 'name' => __( 'View', 'woocommerce' ), + ), + 'cancel' => array( + 'url' => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ), + 'name' => __( 'Cancel', 'woocommerce' ), + ), + ); + + if ( ! $order->needs_payment() ) { + unset( $actions['pay'] ); + } + + if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) { + unset( $actions['cancel'] ); + } + + return apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ); +} + /** * Returns an array of a user's saved payments list for output on the account tab. * diff --git a/templates/myaccount/my-orders.php b/templates/myaccount/my-orders.php index 417b0c09c31..45d40445928 100644 --- a/templates/myaccount/my-orders.php +++ b/templates/myaccount/my-orders.php @@ -69,34 +69,13 @@ if ( $customer_orders ) : ?> array( - 'url' => $order->get_checkout_payment_url(), - 'name' => __( 'Pay', 'woocommerce' ), - ), - 'view' => array( - 'url' => $order->get_view_order_url(), - 'name' => __( 'View', 'woocommerce' ), - ), - 'cancel' => array( - 'url' => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ), - 'name' => __( 'Cancel', 'woocommerce' ), - ), - ); - - if ( ! $order->needs_payment() ) { - unset( $actions['pay'] ); - } - - if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) { - unset( $actions['cancel'] ); - } - - if ( $actions = apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ) ) { - foreach ( $actions as $key => $action ) { - echo '' . esc_html( $action['name'] ) . ''; - } + $actions = wc_get_account_orders_actions( $order ); + + if ( ! empty( $actions ) ) { + foreach ( $actions as $key => $action ) { + echo '' . esc_html( $action['name'] ) . ''; } + } ?> diff --git a/templates/myaccount/orders.php b/templates/myaccount/orders.php index 528ac40adae..e8c329e19d2 100644 --- a/templates/myaccount/orders.php +++ b/templates/myaccount/orders.php @@ -15,7 +15,7 @@ * @see https://docs.woocommerce.com/document/template-structure/ * @author WooThemes * @package WooCommerce/Templates - * @version 3.0.0 + * @version 3.2.0 */ if ( ! defined( 'ABSPATH' ) ) { @@ -65,34 +65,13 @@ do_action( 'woocommerce_before_account_orders', $has_orders ); ?> array( - 'url' => $order->get_checkout_payment_url(), - 'name' => __( 'Pay', 'woocommerce' ), - ), - 'view' => array( - 'url' => $order->get_view_order_url(), - 'name' => __( 'View', 'woocommerce' ), - ), - 'cancel' => array( - 'url' => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ), - 'name' => __( 'Cancel', 'woocommerce' ), - ), - ); - - if ( ! $order->needs_payment() ) { - unset( $actions['pay'] ); - } - - if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) { - unset( $actions['cancel'] ); - } - - if ( $actions = apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ) ) { - foreach ( $actions as $key => $action ) { - echo '' . esc_html( $action['name'] ) . ''; - } + $actions = wc_get_account_orders_actions( $order ); + + if ( ! empty( $actions ) ) { + foreach ( $actions as $key => $action ) { + echo '' . esc_html( $action['name'] ) . ''; } + } ?> From b64d855d96e0192bf533b5be04297aa4506c7869 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Tue, 18 Jul 2017 15:18:53 +0100 Subject: [PATCH 027/127] Introduce `wc_get_account_formatted_address` function which removes a bunch of logic outside of the my-account template file. --- includes/wc-account-functions.php | 30 ++++++++++++++++++++++++++++++ templates/myaccount/my-address.php | 21 ++------------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/includes/wc-account-functions.php b/includes/wc-account-functions.php index a05f5acc872..20a35a3adbb 100644 --- a/includes/wc-account-functions.php +++ b/includes/wc-account-functions.php @@ -240,6 +240,36 @@ function wc_get_account_payment_methods_types() { ) ); } +/** + * Get account formatted address. + * + * @since 3.2.0 + * @param string $name + * @return string + */ +function wc_get_account_formatted_address( $name ) { + $customer_id = get_current_user_id(); + $meta_keys = [ + 'first_name', + 'last_name', + 'company', + 'address_1', + 'address_2', + 'city', + 'postcode', + 'country', + ]; + + $meta = []; + foreach ( $meta_keys as $key ) { + $meta[ $key ] = get_user_meta( $customer_id, $name . '_' . $key, true ); + } + + $address = apply_filters( 'woocommerce_my_account_my_address_formatted_address', $meta, $customer_id, $name ); + + return WC()->countries->get_formatted_address( $address ); +} + /** * Returns an array of a user's saved payments list for output on the account tab. * diff --git a/templates/myaccount/my-address.php b/templates/myaccount/my-address.php index db51bc2aa41..420c414ceca 100644 --- a/templates/myaccount/my-address.php +++ b/templates/myaccount/my-address.php @@ -54,25 +54,8 @@ $col = 1;
get_user_meta( $customer_id, $name . '_first_name', true ), - 'last_name' => get_user_meta( $customer_id, $name . '_last_name', true ), - 'company' => get_user_meta( $customer_id, $name . '_company', true ), - 'address_1' => get_user_meta( $customer_id, $name . '_address_1', true ), - 'address_2' => get_user_meta( $customer_id, $name . '_address_2', true ), - 'city' => get_user_meta( $customer_id, $name . '_city', true ), - 'state' => get_user_meta( $customer_id, $name . '_state', true ), - 'postcode' => get_user_meta( $customer_id, $name . '_postcode', true ), - 'country' => get_user_meta( $customer_id, $name . '_country', true ), - ), $customer_id, $name ); - - $formatted_address = WC()->countries->get_formatted_address( $address ); - - if ( ! $formatted_address ) { - _e( 'You have not set up this type of address yet.', 'woocommerce' ); - } else { - echo $formatted_address; - } + $address = wc_get_account_formatted_address( $name ); + echo $address ? $address : __( 'You have not set up this type of address yet.', 'woocommerce' ); ?>
From 25038f6d0fa7641ec690321f2a7d1d3eed0deed9 Mon Sep 17 00:00:00 2001 From: Nick Hoobin Date: Tue, 18 Jul 2017 10:38:36 -0500 Subject: [PATCH 028/127] Add a filter to arguments passed to wc_get_products during prepare_data_to_export() --- includes/export/class-wc-product-csv-exporter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/export/class-wc-product-csv-exporter.php b/includes/export/class-wc-product-csv-exporter.php index 994ce0cbb15..e65a655ddb5 100644 --- a/includes/export/class-wc-product-csv-exporter.php +++ b/includes/export/class-wc-product-csv-exporter.php @@ -124,7 +124,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter { */ public function prepare_data_to_export() { $columns = $this->get_column_names(); - $products = wc_get_products( array( + $args = apply_filters( "woocommerce_product_export_{$this->export_type}_query_args", array( 'status' => array( 'private', 'publish' ), 'type' => $this->product_types_to_export, 'limit' => $this->get_limit(), @@ -135,6 +135,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter { 'return' => 'objects', 'paginate' => true, ) ); + $products = wc_get_products( $args ); $this->total_rows = $products->total; $this->row_data = array(); From 55100562b3073aacc29ee96a50dd86d48754a1bd Mon Sep 17 00:00:00 2001 From: jaydeeprami Date: Wed, 19 Jul 2017 08:14:41 +0530 Subject: [PATCH 029/127] Fix typo in '@oaram' to '@param' --- includes/data-stores/class-wc-customer-data-store.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/includes/data-stores/class-wc-customer-data-store.php b/includes/data-stores/class-wc-customer-data-store.php index d6596487d5c..1a0f800161a 100644 --- a/includes/data-stores/class-wc-customer-data-store.php +++ b/includes/data-stores/class-wc-customer-data-store.php @@ -369,8 +369,9 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat /** * Search customers and return customer IDs. * - * @param string $term - * @oaram int|string $limit @since 3.0.7 + * @param string $term + * @param int|string $limit @since 3.0.7 + * * @return array */ public function search_customers( $term, $limit = '' ) { From 8d277a263be3d3051368b3d4f4f2edf5d476f279 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jul 2017 10:16:50 +0100 Subject: [PATCH 030/127] Sort by order + zone ID as a fallback in shipping zones Fixes #16170 --- assets/js/admin/wc-shipping-zones.js | 8 +++++--- assets/js/admin/wc-shipping-zones.min.js | 2 +- .../data-stores/class-wc-shipping-zone-data-store.php | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/assets/js/admin/wc-shipping-zones.js b/assets/js/admin/wc-shipping-zones.js index c4eaeea9e85..79026f2d964 100644 --- a/assets/js/admin/wc-shipping-zones.js +++ b/assets/js/admin/wc-shipping-zones.js @@ -102,9 +102,11 @@ if ( _.size( zones ) ) { // Sort zones - zones = _.sortBy( zones, function( zone ) { - return parseInt( zone.zone_order, 10 ); - } ); + zones = _( zones ) + .chain() + .sortBy( function ( zone ) { return parseInt( zone.zone_id, 10 ); } ) + .sortBy( function ( zone ) { return parseInt( zone.zone_order, 10 ); } ) + .value(); // Populate $tbody with the current zones $.each( zones, function( id, rowData ) { diff --git a/assets/js/admin/wc-shipping-zones.min.js b/assets/js/admin/wc-shipping-zones.min.js index e0d923138b7..66498e7fc0e 100644 --- a/assets/js/admin/wc-shipping-zones.min.js +++ b/assets/js/admin/wc-shipping-zones.min.js @@ -1 +1 @@ -!function(e,n,i,o){e(function(){var t=e(".wc-shipping-zones"),s=e(".wc-shipping-zone-rows"),d=e(".wc-shipping-zone-save"),a=i.template("wc-shipping-zone-row"),r=i.template("wc-shipping-zone-row-blank"),l=Backbone.Model.extend({changes:{},logChanges:function(e){var n=this.changes||{};_.each(e,function(e,i){n[i]=_.extend(n[i]||{zone_id:i},e)}),this.changes=n,this.trigger("change:zones")},discardChanges:function(e){var n=this.changes||{},i=null,o=_.indexBy(this.get("zones"),"zone_id");n[e]&&n[e].zone_order!==undefined&&(i=n[e].zone_order),delete n[e],null!==i&&o[e]&&o[e].zone_order!==i&&(n[e]=_.extend(n[e]||{},{zone_id:e,zone_order:i})),this.changes=n,0===_.size(this.changes)&&p.clearUnloadConfirmation()},save:function(){_.size(this.changes)?e.post(o+(o.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:n.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):h.trigger("saved:zones")},onSaveResponse:function(e,i){"success"===i&&(e.success?(h.set("zones",e.data.zones),h.trigger("change:zones"),h.changes={},h.trigger("saved:zones")):window.alert(n.strings.save_failed))}}),c=Backbone.View.extend({rowTemplate:a,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),s.on("change",{view:this},this.updateModelOnChange),s.on("sortupdate",{view:this},this.updateModelOnSort),e(window).on("beforeunload",{view:this},this.unloadConfirmation),e(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow)},block:function(){e(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){e(this.el).unblock()},render:function(){var n=_.indexBy(this.model.get("zones"),"zone_id"),i=this;i.$el.empty(),i.unblock(),_.size(n)?(n=_.sortBy(n,function(e){return parseInt(e.zone_order,10)}),e.each(n,function(e,n){i.renderRow(n)})):i.$el.append(r),i.initRows()},renderRow:function(e){var n=this;n.$el.append(n.rowTemplate(e)),n.initRow(e)},initRow:function(e){var n=this,i=n.$el.find('tr[data-id="'+e.zone_id+'"]');n.renderShippingMethods(e.zone_id,e.shipping_methods),i.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow)},initRows:function(){0==e("tbody.wc-shipping-zone-rows tr").length%2?t.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):t.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),e("#tiptip_holder").removeAttr("style"),e("#tiptip_arrow").removeAttr("style"),e(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(i,o){var t=e('.wc-shipping-zones tr[data-id="'+i+'"]').find(".wc-shipping-zone-methods ul");t.find(".wc-shipping-zone-method").remove(),_.size(o)?(o=_.sortBy(o,function(e){return parseInt(e.method_order,10)}),_.each(o,function(e){var n="method_disabled";"yes"===e.enabled&&(n="method_enabled"),t.append('
  • '+e.title+"
  • ")})):t.append('
  • '+n.strings.no_shipping_methods_offered+"
  • ")},onDeleteRow:function(i){var o=i.data.view.model,t=_.indexBy(o.get("zones"),"zone_id"),s={},d=e(this).closest("tr").data("id");i.preventDefault(),window.confirm(n.strings.delete_confirmation_msg)&&t[d]&&(delete t[d],s[d]=_.extend(s[d]||{},{deleted:"deleted"}),o.set("zones",t),o.logChanges(s),i.data.view.block(),i.data.view.model.save())},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,d.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,d.prop("disabled",!0)},unloadConfirmation:function(e){if(e.data.view.needsUnloadConfirm)return e.returnValue=n.strings.unload_confirmation_msg,window.event.returnValue=n.strings.unload_confirmation_msg,n.strings.unload_confirmation_msg},updateModelOnChange:function(n){var i=n.data.view.model,o=e(n.target),t=o.closest("tr").data("id"),s=o.data("attribute"),d=o.val(),a=_.indexBy(i.get("zones"),"zone_id"),r={};a[t]&&a[t][s]===d||(r[t]={},r[t][s]=d),i.logChanges(r)},updateModelOnSort:function(n){var i=n.data.view.model,o=_.indexBy(i.get("zones"),"zone_id"),t=e("tbody.wc-shipping-zone-rows tr"),s={};_.each(t,function(n){var i=e(n).data("id"),t=null,d=parseInt(e(n).index(),10);o[i]&&(t=parseInt(o[i].zone_order,10)),t!==d&&(s[i]=_.extend(s[i]||{},{zone_order:d}))}),_.size(s)&&(i.logChanges(s),n.data.view.block(),n.data.view.model.save())}}),h=new l({zones:n.zones}),p=new c({model:h,el:s});p.render(),s.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(e,n,i,o){e(function(){var t=e(".wc-shipping-zones"),s=e(".wc-shipping-zone-rows"),d=e(".wc-shipping-zone-save"),a=i.template("wc-shipping-zone-row"),r=i.template("wc-shipping-zone-row-blank"),l=Backbone.Model.extend({changes:{},logChanges:function(e){var n=this.changes||{};_.each(e,function(e,i){n[i]=_.extend(n[i]||{zone_id:i},e)}),this.changes=n,this.trigger("change:zones")},discardChanges:function(e){var n=this.changes||{},i=null,o=_.indexBy(this.get("zones"),"zone_id");n[e]&&n[e].zone_order!==undefined&&(i=n[e].zone_order),delete n[e],null!==i&&o[e]&&o[e].zone_order!==i&&(n[e]=_.extend(n[e]||{},{zone_id:e,zone_order:i})),this.changes=n,0===_.size(this.changes)&&p.clearUnloadConfirmation()},save:function(){_.size(this.changes)?e.post(o+(o.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:n.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):h.trigger("saved:zones")},onSaveResponse:function(e,i){"success"===i&&(e.success?(h.set("zones",e.data.zones),h.trigger("change:zones"),h.changes={},h.trigger("saved:zones")):window.alert(n.strings.save_failed))}}),c=Backbone.View.extend({rowTemplate:a,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),s.on("change",{view:this},this.updateModelOnChange),s.on("sortupdate",{view:this},this.updateModelOnSort),e(window).on("beforeunload",{view:this},this.unloadConfirmation),e(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow)},block:function(){e(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){e(this.el).unblock()},render:function(){var n=_.indexBy(this.model.get("zones"),"zone_id"),i=this;i.$el.empty(),i.unblock(),_.size(n)?(n=_(n).chain().sortBy(function(e){return-1*parseInt(e.zone_id,10)}).sortBy(function(e){return parseInt(e.zone_order,10)}).value(),e.each(n,function(e,n){i.renderRow(n)})):i.$el.append(r),i.initRows()},renderRow:function(e){var n=this;n.$el.append(n.rowTemplate(e)),n.initRow(e)},initRow:function(e){var n=this,i=n.$el.find('tr[data-id="'+e.zone_id+'"]');n.renderShippingMethods(e.zone_id,e.shipping_methods),i.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow)},initRows:function(){0==e("tbody.wc-shipping-zone-rows tr").length%2?t.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):t.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),e("#tiptip_holder").removeAttr("style"),e("#tiptip_arrow").removeAttr("style"),e(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(i,o){var t=e('.wc-shipping-zones tr[data-id="'+i+'"]').find(".wc-shipping-zone-methods ul");t.find(".wc-shipping-zone-method").remove(),_.size(o)?(o=_.sortBy(o,function(e){return parseInt(e.method_order,10)}),_.each(o,function(e){var n="method_disabled";"yes"===e.enabled&&(n="method_enabled"),t.append('
  • '+e.title+"
  • ")})):t.append('
  • '+n.strings.no_shipping_methods_offered+"
  • ")},onDeleteRow:function(i){var o=i.data.view.model,t=_.indexBy(o.get("zones"),"zone_id"),s={},d=e(this).closest("tr").data("id");i.preventDefault(),window.confirm(n.strings.delete_confirmation_msg)&&t[d]&&(delete t[d],s[d]=_.extend(s[d]||{},{deleted:"deleted"}),o.set("zones",t),o.logChanges(s),i.data.view.block(),i.data.view.model.save())},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,d.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,d.prop("disabled",!0)},unloadConfirmation:function(e){if(e.data.view.needsUnloadConfirm)return e.returnValue=n.strings.unload_confirmation_msg,window.event.returnValue=n.strings.unload_confirmation_msg,n.strings.unload_confirmation_msg},updateModelOnChange:function(n){var i=n.data.view.model,o=e(n.target),t=o.closest("tr").data("id"),s=o.data("attribute"),d=o.val(),a=_.indexBy(i.get("zones"),"zone_id"),r={};a[t]&&a[t][s]===d||(r[t]={},r[t][s]=d),i.logChanges(r)},updateModelOnSort:function(n){var i=n.data.view.model,o=_.indexBy(i.get("zones"),"zone_id"),t=e("tbody.wc-shipping-zone-rows tr"),s={};_.each(t,function(n){var i=e(n).data("id"),t=null,d=parseInt(e(n).index(),10);o[i]&&(t=parseInt(o[i].zone_order,10)),t!==d&&(s[i]=_.extend(s[i]||{},{zone_order:d}))}),_.size(s)&&(i.logChanges(s),n.data.view.block(),n.data.view.model.save())}}),h=new l({zones:n.zones}),p=new c({model:h,el:s});p.render(),s.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/includes/data-stores/class-wc-shipping-zone-data-store.php b/includes/data-stores/class-wc-shipping-zone-data-store.php index b1cff12151e..f9ff319439f 100644 --- a/includes/data-stores/class-wc-shipping-zone-data-store.php +++ b/includes/data-stores/class-wc-shipping-zone-data-store.php @@ -220,7 +220,7 @@ class WC_Shipping_Zone_Data_Store extends WC_Data_Store_WP implements WC_Shippin SELECT zones.zone_id FROM {$wpdb->prefix}woocommerce_shipping_zones as zones LEFT OUTER JOIN {$wpdb->prefix}woocommerce_shipping_zone_locations as locations ON zones.zone_id = locations.zone_id AND location_type != 'postcode' WHERE " . implode( ' ', $criteria ) . " - ORDER BY zone_order ASC LIMIT 1 + ORDER BY zone_order ASC, zone_id ASC LIMIT 1 " ); } @@ -232,7 +232,7 @@ class WC_Shipping_Zone_Data_Store extends WC_Data_Store_WP implements WC_Shippin */ public function get_zones() { global $wpdb; - return $wpdb->get_results( "SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC;" ); + return $wpdb->get_results( "SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC, zone_id ASC;" ); } From 28cb0909c84508b30dbae4c41ac82a4cddcb7d5e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jul 2017 14:25:00 +0100 Subject: [PATCH 031/127] Add placeholders array used in descriptions and for find and replace Fixes #16156 --- .../emails/class-wc-email-cancelled-order.php | 23 ++++--- ...lass-wc-email-customer-completed-order.php | 20 +++--- .../class-wc-email-customer-invoice.php | 19 +++--- .../class-wc-email-customer-new-account.php | 3 - .../emails/class-wc-email-customer-note.php | 20 +++--- .../class-wc-email-customer-on-hold-order.php | 30 ++++----- ...ass-wc-email-customer-processing-order.php | 17 ++--- ...class-wc-email-customer-refunded-order.php | 17 ++--- .../emails/class-wc-email-failed-order.php | 23 ++++--- includes/emails/class-wc-email-new-order.php | 23 ++++--- includes/emails/class-wc-email.php | 62 +++++++++++-------- 11 files changed, 135 insertions(+), 122 deletions(-) diff --git a/includes/emails/class-wc-email-cancelled-order.php b/includes/emails/class-wc-email-cancelled-order.php index 8dbac9969c3..1791a3fd402 100644 --- a/includes/emails/class-wc-email-cancelled-order.php +++ b/includes/emails/class-wc-email-cancelled-order.php @@ -23,11 +23,16 @@ class WC_Email_Cancelled_Order extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'cancelled_order'; - $this->title = __( 'Cancelled order', 'woocommerce' ); - $this->description = __( 'Cancelled order emails are sent to chosen recipient(s) when orders have been marked cancelled (if they were previously processing or on-hold).', 'woocommerce' ); - $this->template_html = 'emails/admin-cancelled-order.php'; - $this->template_plain = 'emails/plain/admin-cancelled-order.php'; + $this->id = 'cancelled_order'; + $this->title = __( 'Cancelled order', 'woocommerce' ); + $this->description = __( 'Cancelled order emails are sent to chosen recipient(s) when orders have been marked cancelled (if they were previously processing or on-hold).', 'woocommerce' ); + $this->template_html = 'emails/admin-cancelled-order.php'; + $this->template_plain = 'emails/plain/admin-cancelled-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_status_processing_to_cancelled_notification', array( $this, 'trigger' ), 10, 2 ); @@ -72,11 +77,9 @@ class WC_Email_Cancelled_Order extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email-customer-completed-order.php b/includes/emails/class-wc-email-customer-completed-order.php index 6146606a669..c986ddbfa99 100644 --- a/includes/emails/class-wc-email-customer-completed-order.php +++ b/includes/emails/class-wc-email-customer-completed-order.php @@ -23,15 +23,17 @@ class WC_Email_Customer_Completed_Order extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'customer_completed_order'; $this->customer_email = true; - $this->title = __( 'Completed order', 'woocommerce' ); $this->description = __( 'Order complete emails are sent to customers when their orders are marked completed and usually indicate that their orders have been shipped.', 'woocommerce' ); - $this->template_html = 'emails/customer-completed-order.php'; $this->template_plain = 'emails/plain/customer-completed-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_status_completed_notification', array( $this, 'trigger' ), 10, 2 ); @@ -52,14 +54,10 @@ class WC_Email_Customer_Completed_Order extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->recipient = $this->object->get_billing_email(); - - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email-customer-invoice.php b/includes/emails/class-wc-email-customer-invoice.php index d585621bde5..9cc37b15d46 100644 --- a/includes/emails/class-wc-email-customer-invoice.php +++ b/includes/emails/class-wc-email-customer-invoice.php @@ -37,14 +37,17 @@ class WC_Email_Customer_Invoice extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'customer_invoice'; $this->customer_email = true; - $this->title = __( 'Customer invoice', 'woocommerce' ); $this->description = __( 'Customer invoice emails can be sent to customers containing their order information and payment links.', 'woocommerce' ); $this->template_html = 'emails/customer-invoice.php'; $this->template_plain = 'emails/plain/customer-invoice.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Call parent constructor parent::__construct(); @@ -126,14 +129,10 @@ class WC_Email_Customer_Invoice extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->recipient = $this->object->get_billing_email(); - - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email-customer-new-account.php b/includes/emails/class-wc-email-customer-new-account.php index c9a0ddc25e6..c161cb0305e 100644 --- a/includes/emails/class-wc-email-customer-new-account.php +++ b/includes/emails/class-wc-email-customer-new-account.php @@ -51,13 +51,10 @@ class WC_Email_Customer_New_Account extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'customer_new_account'; $this->customer_email = true; - $this->title = __( 'New account', 'woocommerce' ); $this->description = __( 'Customer "new account" emails are sent to the customer when a customer signs up via checkout or account pages.', 'woocommerce' ); - $this->template_html = 'emails/customer-new-account.php'; $this->template_plain = 'emails/plain/customer-new-account.php'; diff --git a/includes/emails/class-wc-email-customer-note.php b/includes/emails/class-wc-email-customer-note.php index 2c9bc939eec..7dda8552d21 100644 --- a/includes/emails/class-wc-email-customer-note.php +++ b/includes/emails/class-wc-email-customer-note.php @@ -30,15 +30,17 @@ class WC_Email_Customer_Note extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'customer_note'; $this->customer_email = true; - $this->title = __( 'Customer note', 'woocommerce' ); $this->description = __( 'Customer note emails are sent when you add a note to an order.', 'woocommerce' ); - $this->template_html = 'emails/customer-note.php'; $this->template_plain = 'emails/plain/customer-note.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers add_action( 'woocommerce_new_customer_note_notification', array( $this, 'trigger' ) ); @@ -84,14 +86,10 @@ class WC_Email_Customer_Note extends WC_Email { extract( $args ); if ( $order_id && ( $this->object = wc_get_order( $order_id ) ) ) { - $this->recipient = $this->object->get_billing_email(); - $this->customer_note = $customer_note; - - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->recipient = $this->object->get_billing_email(); + $this->customer_note = $customer_note; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } else { return; } diff --git a/includes/emails/class-wc-email-customer-on-hold-order.php b/includes/emails/class-wc-email-customer-on-hold-order.php index 300e8516c00..772b8af7b69 100644 --- a/includes/emails/class-wc-email-customer-on-hold-order.php +++ b/includes/emails/class-wc-email-customer-on-hold-order.php @@ -23,13 +23,17 @@ class WC_Email_Customer_On_Hold_Order extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'customer_on_hold_order'; - $this->customer_email = true; - - $this->title = __( 'Order on-hold', 'woocommerce' ); - $this->description = __( 'This is an order notification sent to customers containing order details after an order is placed on-hold.', 'woocommerce' ); - $this->template_html = 'emails/customer-on-hold-order.php'; - $this->template_plain = 'emails/plain/customer-on-hold-order.php'; + $this->id = 'customer_on_hold_order'; + $this->customer_email = true; + $this->title = __( 'Order on-hold', 'woocommerce' ); + $this->description = __( 'This is an order notification sent to customers containing order details after an order is placed on-hold.', 'woocommerce' ); + $this->template_html = 'emails/customer-on-hold-order.php'; + $this->template_plain = 'emails/plain/customer-on-hold-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); @@ -71,14 +75,10 @@ class WC_Email_Customer_On_Hold_Order extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->recipient = $this->object->get_billing_email(); - - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email-customer-processing-order.php b/includes/emails/class-wc-email-customer-processing-order.php index 85980d9f1f5..295e72d3c14 100644 --- a/includes/emails/class-wc-email-customer-processing-order.php +++ b/includes/emails/class-wc-email-customer-processing-order.php @@ -30,6 +30,11 @@ class WC_Email_Customer_Processing_Order extends WC_Email { $this->description = __( 'This is an order notification sent to customers containing order details after payment.', 'woocommerce' ); $this->template_html = 'emails/customer-processing-order.php'; $this->template_plain = 'emails/plain/customer-processing-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); @@ -72,14 +77,10 @@ class WC_Email_Customer_Processing_Order extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->recipient = $this->object->get_billing_email(); - - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email-customer-refunded-order.php b/includes/emails/class-wc-email-customer-refunded-order.php index 8a17908efbf..c2852600cee 100644 --- a/includes/emails/class-wc-email-customer-refunded-order.php +++ b/includes/emails/class-wc-email-customer-refunded-order.php @@ -43,6 +43,11 @@ class WC_Email_Customer_Refunded_Order extends WC_Email { $this->description = __( 'Order refunded emails are sent to customers when their orders are refunded.', 'woocommerce' ); $this->template_html = 'emails/customer-refunded-order.php'; $this->template_plain = 'emails/plain/customer-refunded-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_fully_refunded_notification', array( $this, 'trigger_full' ), 10, 2 ); @@ -148,14 +153,10 @@ class WC_Email_Customer_Refunded_Order extends WC_Email { $this->id = $this->partial_refund ? 'customer_partially_refunded_order' : 'customer_refunded_order'; if ( $order_id ) { - $this->object = wc_get_order( $order_id ); - $this->recipient = $this->object->get_billing_email(); - - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = wc_get_order( $order_id ); + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! empty( $refund_id ) ) { diff --git a/includes/emails/class-wc-email-failed-order.php b/includes/emails/class-wc-email-failed-order.php index 0b0ff5927e5..586cdfaa24f 100644 --- a/includes/emails/class-wc-email-failed-order.php +++ b/includes/emails/class-wc-email-failed-order.php @@ -23,11 +23,16 @@ class WC_Email_Failed_Order extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'failed_order'; - $this->title = __( 'Failed order', 'woocommerce' ); - $this->description = __( 'Failed order emails are sent to chosen recipient(s) when orders have been marked failed (if they were previously processing or on-hold).', 'woocommerce' ); - $this->template_html = 'emails/admin-failed-order.php'; - $this->template_plain = 'emails/plain/admin-failed-order.php'; + $this->id = 'failed_order'; + $this->title = __( 'Failed order', 'woocommerce' ); + $this->description = __( 'Failed order emails are sent to chosen recipient(s) when orders have been marked failed (if they were previously processing or on-hold).', 'woocommerce' ); + $this->template_html = 'emails/admin-failed-order.php'; + $this->template_plain = 'emails/plain/admin-failed-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_status_pending_to_failed_notification', array( $this, 'trigger' ), 10, 2 ); @@ -72,11 +77,9 @@ class WC_Email_Failed_Order extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email-new-order.php b/includes/emails/class-wc-email-new-order.php index 911c3f4e7a6..bfbd165f4a5 100644 --- a/includes/emails/class-wc-email-new-order.php +++ b/includes/emails/class-wc-email-new-order.php @@ -23,11 +23,16 @@ class WC_Email_New_Order extends WC_Email { * Constructor. */ public function __construct() { - $this->id = 'new_order'; - $this->title = __( 'New order', 'woocommerce' ); - $this->description = __( 'New order emails are sent to chosen recipient(s) when a new order is received.', 'woocommerce' ); - $this->template_html = 'emails/admin-new-order.php'; - $this->template_plain = 'emails/plain/admin-new-order.php'; + $this->id = 'new_order'; + $this->title = __( 'New order', 'woocommerce' ); + $this->description = __( 'New order emails are sent to chosen recipient(s) when a new order is received.', 'woocommerce' ); + $this->template_html = 'emails/admin-new-order.php'; + $this->template_plain = 'emails/plain/admin-new-order.php'; + $this->placeholders = array( + '{site_title}' => $this->get_blogname(), + '{order_date}' => '', + '{order_number}' => '', + ); // Triggers for this email add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); @@ -76,11 +81,9 @@ class WC_Email_New_Order extends WC_Email { } if ( is_a( $order, 'WC_Order' ) ) { - $this->object = $order; - $this->find['order-date'] = '{order_date}'; - $this->find['order-number'] = '{order_number}'; - $this->replace['order-date'] = wc_format_datetime( $this->object->get_date_created() ); - $this->replace['order-number'] = $this->object->get_order_number(); + $this->object = $order; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { diff --git a/includes/emails/class-wc-email.php b/includes/emails/class-wc-email.php index f96f84bc99b..62795af8a17 100644 --- a/includes/emails/class-wc-email.php +++ b/includes/emails/class-wc-email.php @@ -95,18 +95,6 @@ class WC_Email extends WC_Settings_API { */ public $object; - /** - * Strings to find in subjects/headings. - * @var array - */ - public $find = array(); - - /** - * Strings to replace in subjects/headings. - * @var array - */ - public $replace = array(); - /** * Mime boundary (for multipart emails). * @var string @@ -195,34 +183,54 @@ class WC_Email extends WC_Settings_API { ' ', // Runs of spaces, post-handling ); + /** + * Strings to find/replace in subjects/headings. + * + * @var array + */ + protected $placeholders = array(); + + /** + * Strings to find in subjects/headings. + * + * @deprecated 3.2.0 in favour of placeholders + * @var array + */ + public $find = array(); + + /** + * Strings to replace in subjects/headings. + * + * @deprecated 3.2.0 in favour of placeholders + * @var array + */ + public $replace = array(); + /** * Constructor. */ public function __construct() { + // Find/replace + if ( empty( $this->placeholders ) ) { + $this->placeholders = array( + '{site_title}' => $this->get_blogname() + ); + } + // Init settings $this->init_form_fields(); $this->init_settings(); - // Save settings hook - add_action( 'woocommerce_update_options_email_' . $this->id, array( $this, 'process_admin_options' ) ); - // Default template base if not declared in child constructor if ( is_null( $this->template_base ) ) { $this->template_base = WC()->plugin_path() . '/templates/'; } - // Settings $this->email_type = $this->get_option( 'email_type' ); $this->enabled = $this->get_option( 'enabled' ); - // Find/replace - $this->find['blogname'] = '{blogname}'; - $this->find['site-title'] = '{site_title}'; - $this->replace['blogname'] = $this->get_blogname(); - $this->replace['site-title'] = $this->get_blogname(); - - // For multipart messages add_action( 'phpmailer_init', array( $this, 'handle_multipart' ) ); + add_action( 'woocommerce_update_options_email_' . $this->id, array( $this, 'process_admin_options' ) ); } /** @@ -246,7 +254,9 @@ class WC_Email extends WC_Settings_API { * @return string */ public function format_string( $string ) { - return str_replace( apply_filters( 'woocommerce_email_format_string_find', $this->find, $this ), apply_filters( 'woocommerce_email_format_string_replace', $this->replace, $this ), $string ); + // handle legacy find and replace. + $string = str_replace( $this->find, $this->replace, $string ); + return str_replace( apply_filters( 'woocommerce_email_format_string_find', array_keys( $this->placeholders ), $this ), apply_filters( 'woocommerce_email_format_string_replace', array_values( $this->placeholders ), $this ), $string ); } /** @@ -538,7 +548,7 @@ class WC_Email extends WC_Settings_API { 'type' => 'text', 'desc_tip' => true, /* translators: %s: list of placeholders */ - 'description' => sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '{site_title}' ), + 'description' => sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . implode( ', ', array_keys( $this->placeholders ) ) . '' ), 'placeholder' => $this->get_default_subject(), 'default' => '', ), @@ -547,7 +557,7 @@ class WC_Email extends WC_Settings_API { 'type' => 'text', 'desc_tip' => true, /* translators: %s: list of placeholders */ - 'description' => sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '{site_title}' ), + 'description' => sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . implode( ', ', array_keys( $this->placeholders ) ) . '' ), 'placeholder' => $this->get_default_heading(), 'default' => '', ), From 16870c9c255aaf3cafe6168e29be8015990bc40f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jul 2017 14:30:47 +0100 Subject: [PATCH 032/127] Fix copy pasta errors in refunded email template Closes #16157 --- includes/emails/class-wc-email-customer-refunded-order.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/emails/class-wc-email-customer-refunded-order.php b/includes/emails/class-wc-email-customer-refunded-order.php index 8a17908efbf..f09b859d986 100644 --- a/includes/emails/class-wc-email-customer-refunded-order.php +++ b/includes/emails/class-wc-email-customer-refunded-order.php @@ -74,9 +74,9 @@ class WC_Email_Customer_Refunded_Order extends WC_Email { */ public function get_default_heading( $partial = false ) { if ( $partial ) { - return __( 'Order {order_number} details', 'woocommerce' ); - } else { return __( 'Your order has been partially refunded', 'woocommerce' ); + } else { + return __( 'Order {order_number} details', 'woocommerce' ); } } @@ -90,7 +90,7 @@ class WC_Email_Customer_Refunded_Order extends WC_Email { if ( $this->partial_refund ) { $subject = $this->get_option( 'subject_partial', $this->get_default_subject( true ) ); } else { - $subject = $this->get_option( 'subject_full', $this->get_default_heading() ); + $subject = $this->get_option( 'subject_full', $this->get_default_subject() ); } return apply_filters( 'woocommerce_email_subject_customer_refunded_order', $this->format_string( $subject ), $this->object ); } From 578da2d1262d37a56370beb3092807da7cf703e7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jul 2017 14:58:46 +0100 Subject: [PATCH 033/127] Unchecked checkbox should be an empty string Closes #16184 --- includes/class-wc-checkout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-checkout.php b/includes/class-wc-checkout.php index d176435df38..0984e30c510 100644 --- a/includes/class-wc-checkout.php +++ b/includes/class-wc-checkout.php @@ -562,7 +562,7 @@ class WC_Checkout { switch ( $type ) { case 'checkbox' : - $value = (int) isset( $_POST[ $key ] ); + $value = isset( $_POST[ $key ] ) ? 1 : ''; break; case 'multiselect' : $value = isset( $_POST[ $key ] ) ? implode( ', ', wc_clean( $_POST[ $key ] ) ) : ''; From 916294b7d039fd83ccf2593b7a774a46e490a985 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jul 2017 15:18:33 +0100 Subject: [PATCH 034/127] Use comment_status input name Closes #16153 --- includes/admin/meta-boxes/class-wc-meta-box-product-data.php | 2 +- includes/admin/meta-boxes/views/html-product-data-advanced.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php index d49517932d4..616fd65f132 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php @@ -357,7 +357,7 @@ class WC_Meta_Box_Product_Data { 'product_url' => esc_url_raw( $_POST['_product_url'] ), 'button_text' => wc_clean( $_POST['_button_text'] ), 'children' => 'grouped' === $product_type ? self::prepare_children() : null, - 'reviews_allowed' => ! empty( $_POST['_reviews_allowed'] ), + 'reviews_allowed' => ! empty( $_POST['comment_status'] ) && 'open' === $_POST['comment_status'], 'attributes' => $attributes, 'default_attributes' => self::prepare_set_attributes( $attributes, 'default_attribute_' ), ) ); diff --git a/includes/admin/meta-boxes/views/html-product-data-advanced.php b/includes/admin/meta-boxes/views/html-product-data-advanced.php index 6e31d9eb208..350dadcfa44 100644 --- a/includes/admin/meta-boxes/views/html-product-data-advanced.php +++ b/includes/admin/meta-boxes/views/html-product-data-advanced.php @@ -37,7 +37,7 @@ if ( ! defined( 'ABSPATH' ) ) {
    '_reviews_allowed', + 'id' => 'comment_status', 'value' => $product_object->get_reviews_allowed( 'edit' ) ? 'open' : 'closed', 'label' => __( 'Enable reviews', 'woocommerce' ), 'cbvalue' => 'open', From 68470b51a4d50af983785bbadc0b4538e8ed6044 Mon Sep 17 00:00:00 2001 From: Saul Fautley Date: Wed, 19 Jul 2017 18:53:02 +0200 Subject: [PATCH 035/127] Updated structured data for products - Replaced outdated `priceSpecification` with `AggregateOffer`. - Restructured data according to Google's latest specifications. - Use product short_description if available. --- includes/class-wc-structured-data.php | 67 +++++++++++++++------------ 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/includes/class-wc-structured-data.php b/includes/class-wc-structured-data.php index d689bef9429..1f158de13e8 100644 --- a/includes/class-wc-structured-data.php +++ b/includes/class-wc-structured-data.php @@ -193,54 +193,63 @@ class WC_Structured_Data { return; } - $shop_name = get_bloginfo( 'name' ); - $shop_url = home_url(); - $currency = get_woocommerce_currency(); - $markup = array(); - $markup['@type'] = 'Product'; - $markup['@id'] = get_permalink( $product->get_id() ); - $markup['url'] = $markup['@id']; - $markup['name'] = $product->get_name(); + $shop_name = get_bloginfo( 'name' ); + $shop_url = home_url(); + $currency = get_woocommerce_currency(); + + $markup = array( + '@type' => 'Product', + '@id' => get_permalink( $product->get_id() ), + 'name' => $product->get_name(), + ); if ( apply_filters( 'woocommerce_structured_data_product_limit', is_product_taxonomy() || is_shop() ) ) { + $markup['url'] = $markup['@id']; + $this->set_data( apply_filters( 'woocommerce_structured_data_product_limited', $markup, $product ) ); return; } - if ( '' !== $product->get_price() ) { - $markup_offer = array( - '@type' => 'Offer', - 'priceCurrency' => $currency, - 'availability' => 'https://schema.org/' . $stock = ( $product->is_in_stock() ? 'InStock' : 'OutOfStock' ), - 'sku' => $product->get_sku(), - 'image' => wp_get_attachment_url( $product->get_image_id() ), - 'description' => $product->get_description(), - 'seller' => array( - '@type' => 'Organization', - 'name' => $shop_name, - 'url' => $shop_url, - ), - ); + $markup['image'] = wp_get_attachment_url( $product->get_image_id() ); + $markup['description'] = $product->get_short_description() ?: $product->get_description(); + $markup['sku'] = $product->get_sku(); + if ( '' !== $product->get_price() ) { if ( $product->is_type( 'variable' ) ) { $prices = $product->get_variation_prices(); $lowest = reset( $prices['price'] ); $highest = end( $prices['price'] ); if ( $lowest === $highest ) { - $markup_offer['price'] = wc_format_decimal( $product->get_price(), wc_get_price_decimals() ); + $markup_offer = array( + '@type' => 'Offer', + 'price' => wc_format_decimal( $lowest, wc_get_price_decimals() ), + ); } else { - $markup_offer['priceSpecification'] = array( - 'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ), - 'minPrice' => wc_format_decimal( $lowest, wc_get_price_decimals() ), - 'maxPrice' => wc_format_decimal( $highest, wc_get_price_decimals() ), - 'priceCurrency' => $currency, + $markup_offer = array( + '@type' => 'AggregateOffer', + 'lowPrice' => wc_format_decimal( $lowest, wc_get_price_decimals() ), + 'highPrice' => wc_format_decimal( $highest, wc_get_price_decimals() ), ); } } else { - $markup_offer['price'] = wc_format_decimal( $product->get_price(), wc_get_price_decimals() ); + $markup_offer = array( + '@type' => 'Offer', + 'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ), + ); } + $markup_offer += array( + 'priceCurrency' => $currency, + 'availability' => 'https://schema.org/' . ( $product->is_in_stock() ? 'InStock' : 'OutOfStock' ), + 'url' => $markup['@id'], + 'seller' => array( + '@type' => 'Organization', + 'name' => $shop_name, + 'url' => $shop_url, + ), + ); + $markup['offers'] = array( apply_filters( 'woocommerce_structured_data_product_offer', $markup_offer, $product ) ); } From c569d4fd816c4783bf9037de664b9af10bf63ff2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 11:23:37 +0100 Subject: [PATCH 036/127] Travis --- .travis.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 401d098fb7d..15aa83513d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,8 @@ language: php sudo: false -# Test main supported versions of PHP and HHVM against latest WP. 5.2 is min supported version. +# Test main supported versions of PHP and HHVM against latest WP. php: - - 5.2 - - 5.3 - 5.6 - 7.0 - 7.1 @@ -18,6 +16,12 @@ matrix: include: - php: 5.6 env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 + - php: 5.3 + env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 + dist: precise + - php: 5.2 + env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 + dist: precise before_script: - export PATH="$HOME/.composer/vendor/bin:$PATH" From aa7f8237631251b38f66d5b4da3950e5c48760f9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 11:42:53 +0100 Subject: [PATCH 037/127] Travis config --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 15aa83513d9..1bb1b568cae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ matrix: include: - php: 5.6 env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 + dist: precise - php: 5.3 env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 dist: precise From 3fbba9d869643feaee6f5a320b9c6a183c885214 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 12:00:21 +0100 Subject: [PATCH 038/127] More travis config --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1bb1b568cae..26835b877f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: php sudo: false +dist: trusty + # Test main supported versions of PHP and HHVM against latest WP. php: - 5.6 @@ -18,10 +20,10 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 dist: precise - php: 5.3 - env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 + env: WP_VERSION=master dist: precise - php: 5.2 - env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 + env: WP_VERSION=master dist: precise before_script: From 1c26587948229708963395b3f8f1825e49eeca04 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 12:12:29 +0100 Subject: [PATCH 039/127] travis --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 26835b877f8..4dcde4c2130 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,9 @@ php: - 7.0 - 7.1 +cache: + apt: true + env: - WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 @@ -20,10 +23,10 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 dist: precise - php: 5.3 - env: WP_VERSION=master + env: WP_VERSION=latest dist: precise - php: 5.2 - env: WP_VERSION=master + env: WP_VERSION=latest dist: precise before_script: From d7484336c1d9609e5e1e8dcce33171ca84a77031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20M=C3=B6rchen?= Date: Thu, 20 Jul 2017 13:29:54 +0200 Subject: [PATCH 040/127] Fixed wrong class reference in comment --- includes/wc-template-functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 9900373b170..51d8ed192d1 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -2460,7 +2460,7 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) { /** * Display item meta data. * @since 3.0.0 - * @param WC_Item $item + * @param WC_Order_Item $item * @param array $args * @return string|void */ @@ -2498,7 +2498,7 @@ if ( ! function_exists( 'wc_display_item_downloads' ) ) { /** * Display item download links. * @since 3.0.0 - * @param WC_Item $item + * @param WC_Order_Item $item * @param array $args * @return string|void */ From b14c719fc0890a8a9e93f6132ff7f7776069aab4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 12:39:46 +0100 Subject: [PATCH 041/127] Travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4dcde4c2130..8f17c8a2059 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,10 +23,10 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 dist: precise - php: 5.3 - env: WP_VERSION=latest + env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 dist: precise - php: 5.2 - env: WP_VERSION=latest + env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 dist: precise before_script: From 3faa1c1ee9615cf7b96cfecaa1caa970120b5b58 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 12:48:14 +0100 Subject: [PATCH 042/127] Unset variable prices on read. Closes #16145 --- .../data-stores/class-wc-product-variable-data-store-cpt.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/includes/data-stores/class-wc-product-variable-data-store-cpt.php index d9e243052b8..70e1112ae2a 100644 --- a/includes/data-stores/class-wc-product-variable-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variable-data-store-cpt.php @@ -29,6 +29,10 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple protected function read_product_data( &$product ) { parent::read_product_data( $product ); + // Make sure data which does not apply to variables is unset. + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + // Set directly since individual data needs changed at the WC_Product_Variation level -- these datasets just pull. $children = $this->read_children( $product ); $product->set_children( $children['all'] ); From 8654a94af2efa68e06e96feae9ff14d8de8f3b66 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 13:57:10 +0100 Subject: [PATCH 043/127] update installer --- tests/bin/install.sh | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tests/bin/install.sh b/tests/bin/install.sh index dcea51f3708..521b86fd857 100755 --- a/tests/bin/install.sh +++ b/tests/bin/install.sh @@ -16,15 +16,17 @@ WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi } if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then WP_TESTS_TAG="tags/$WP_VERSION" +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" else # http serves a single offer, whereas https serves multiple. we only want one download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json @@ -47,15 +49,21 @@ install_wp() { mkdir -p $WP_CORE_DIR - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p /tmp/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip + unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ + mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR else - local ARCHIVE_NAME="wordpress-$WP_VERSION" + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR fi - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php } @@ -74,8 +82,6 @@ install_test_suite() { svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes fi - cd $WP_TESTS_DIR - if [ ! -f wp-tests-config.php ]; then download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php From c72e2d6aab54a08df54d150ffcabfafd91115881 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 14:34:16 +0100 Subject: [PATCH 044/127] test --- tests/bin/install.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/bin/install.sh b/tests/bin/install.sh index 521b86fd857..42e677ce263 100755 --- a/tests/bin/install.sh +++ b/tests/bin/install.sh @@ -2,7 +2,7 @@ # see https://github.com/wp-cli/wp-cli/blob/master/templates/install-wp-tests.sh if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version]" + echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" exit 1 fi @@ -11,6 +11,7 @@ DB_USER=$2 DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-latest} +SKIP_DB_CREATE=${6-false} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} @@ -80,11 +81,14 @@ install_test_suite() { # set up testing suite mkdir -p $WP_TESTS_DIR svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data fi if [ ! -f wp-tests-config.php ]; then download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php + # remove all forward slashes in the end + WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php @@ -94,6 +98,11 @@ install_test_suite() { } install_db() { + + if [ ${SKIP_DB_CREATE} = "true" ]; then + return 0 + fi + # parse DB_HOST for port or socket references local PARTS=(${DB_HOST//\:/ }) local DB_HOSTNAME=${PARTS[0]}; From 1f1219599e7a87fe5b680e2145a3482967946240 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 15:00:54 +0100 Subject: [PATCH 045/127] remove quiet --- tests/bin/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bin/install.sh b/tests/bin/install.sh index 42e677ce263..237d3893361 100755 --- a/tests/bin/install.sh +++ b/tests/bin/install.sh @@ -80,8 +80,8 @@ install_test_suite() { if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data + svn co https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data fi if [ ! -f wp-tests-config.php ]; then From 80cbba49d6d2374935c592ccd177ec2c33f541f7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 15:41:28 +0100 Subject: [PATCH 046/127] More test tweaks --- .travis.yml | 5 ----- tests/bin/install.sh | 6 +++--- tests/bin/travis.sh | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8f17c8a2059..035df03dcc1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,6 @@ language: php sudo: false -dist: trusty - # Test main supported versions of PHP and HHVM against latest WP. php: - 5.6 @@ -21,13 +19,10 @@ matrix: include: - php: 5.6 env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 - dist: precise - php: 5.3 env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 - dist: precise - php: 5.2 env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 - dist: precise before_script: - export PATH="$HOME/.composer/vendor/bin:$PATH" diff --git a/tests/bin/install.sh b/tests/bin/install.sh index 237d3893361..8a8b0eb4419 100755 --- a/tests/bin/install.sh +++ b/tests/bin/install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# see https://github.com/wp-cli/wp-cli/blob/master/templates/install-wp-tests.sh +# See https://raw.githubusercontent.com/wp-cli/scaffold-command/master/templates/install-wp-tests.sh if [ $# -lt 3 ]; then echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" @@ -80,8 +80,8 @@ install_test_suite() { if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR - svn co https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes - svn co https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data fi if [ ! -f wp-tests-config.php ]; then diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index 03fbd24c565..b3a64a82f6e 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -20,6 +20,8 @@ if [ $1 == 'before' ]; then elif [ $1 == 'during' ]; then +elif [ $1 == 'after' ]; then + ## Only run on latest stable PHP box (defined in .travis.yml). if [[ ${TRAVIS_PHP_VERSION} == ${PHP_LATEST_STABLE} ]]; then # WordPress Coding Standards. @@ -38,8 +40,6 @@ elif [ $1 == 'during' ]; then ./vendor/bin/phpcs -p -s -n ./**/**/**/**/*.php --standard=./phpcs.ruleset.xml --extensions=php --ignore=./vendor/**/**/*.php --ignore=./tests/**/**/*.php fi -elif [ $1 == 'after' ]; then - ## Only run on master, not pull requests, latest stable PHP box (defined in .travis.yml). if [[ ${TRAVIS_BRANCH} == 'master' ]] && [[ ${TRAVIS_EVENT_TYPE} != 'pull_request' ]] && [[ ${TRAVIS_PHP_VERSION} == ${PHP_LATEST_STABLE} ]]; then wget https://scrutinizer-ci.com/ocular.phar From 20f2c60f2dd46a25a9170c26a191c49d666266fb Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 15:43:40 +0100 Subject: [PATCH 047/127] remove during --- tests/bin/travis.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index b3a64a82f6e..b5731355e8c 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -18,8 +18,6 @@ if [ $1 == 'before' ]; then composer self-update composer install --no-interaction -elif [ $1 == 'during' ]; then - elif [ $1 == 'after' ]; then ## Only run on latest stable PHP box (defined in .travis.yml). From a7fec4475f3dc1788a008f04b082b5624554980d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jul 2017 15:55:45 +0100 Subject: [PATCH 048/127] 5.3 does not like dist --- .travis.yml | 6 ++---- tests/bin/travis.sh | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 035df03dcc1..bc49cf91d6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,6 @@ php: - 7.0 - 7.1 -cache: - apt: true - env: - WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 @@ -21,8 +18,10 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=1 PHP_LATEST_STABLE=7.1 - php: 5.3 env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 + dist: precise - php: 5.2 env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1 + dist: precise before_script: - export PATH="$HOME/.composer/vendor/bin:$PATH" @@ -31,7 +30,6 @@ before_script: script: - bash tests/bin/phpunit.sh - - bash tests/bin/travis.sh during after_script: - bash tests/bin/travis.sh after diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index b5731355e8c..1e3b68851d0 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -9,10 +9,10 @@ if [ $1 == 'before' ]; then # No Xdebug and therefore no coverage in PHP 5.3 [[ ${TRAVIS_PHP_VERSION} == '5.3' ]] && exit; - if [[ ${TRAVIS_PHP_VERSION:0:2} == "7." ]]; then - composer global require "phpunit/phpunit=5.7.*" - else + if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then composer global require "phpunit/phpunit=4.8.*" + else + composer global require "phpunit/phpunit=5.7.*" fi composer self-update From a8e69c2e24af852669e9f93fecf55303d0418e3c Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 12:55:08 -0300 Subject: [PATCH 049/127] Enable external code coverage in Scrutinizer --- .scrutinizer.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 07af2c45c90..543a40cf4ed 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -30,3 +30,5 @@ checks: tools: sensiolabs_security_checker: true + external_code_coverage: + timeout: 600 # Wait 10 minutes for Travis send coverage file. From c7ee52602a21af0af60022b9d106537404363edc Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 13:32:21 -0300 Subject: [PATCH 050/127] Updated PHPUnit version --- composer.json | 2 +- composer.lock | 471 +++++++++++++++++++++++++++++--------------- tests/bin/travis.sh | 2 +- 3 files changed, 309 insertions(+), 166 deletions(-) diff --git a/composer.json b/composer.json index c5263b52868..e0c01286b91 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "require-dev": { "squizlabs/php_codesniffer": "*", "wp-coding-standards/wpcs": "0.10.0", - "phpunit/phpunit": "5.7.19" + "phpunit/phpunit": "6.2.3" }, "scripts": { "post-install-cmd": [ diff --git a/composer.lock b/composer.lock index e548a7eef1b..8135c716e9f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "3e1a8fa4256dcf3ef3caee1b027d6779", + "content-hash": "4028dd750463d5e5ad5f2099196a949a", "packages": [ { "name": "composer/installers", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "d78064c68299743e0161004f2de3a0204e33b804" + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d78064c68299743e0161004f2de3a0204e33b804", - "reference": "d78064c68299743e0161004f2de3a0204e33b804", + "url": "https://api.github.com/repos/composer/installers/zipball/79ad876c7498c0bbfe7eed065b8651c93bfd6045", + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045", "shasum": "" }, "require": { @@ -59,12 +59,16 @@ "keywords": [ "Craft", "Dolibarr", + "Eliasis", "Hurad", "ImageCMS", + "Kanboard", "MODX Evo", "Mautic", + "Maya", "OXID", "Plentymarkets", + "Porto", "RadPHP", "SMF", "Thelia", @@ -87,9 +91,11 @@ "fuelphp", "grav", "installer", + "itop", "joomla", "kohana", "laravel", + "lavalite", "lithium", "magento", "mako", @@ -104,6 +110,7 @@ "roundcube", "shopware", "silverstripe", + "sydes", "symfony", "typo3", "wordpress", @@ -111,7 +118,7 @@ "zend", "zikula" ], - "time": "2016-08-13T20:53:52+00:00" + "time": "2017-04-24T06:37:16+00:00" } ], "packages-dev": [ @@ -211,6 +218,108 @@ ], "time": "2017-04-12T18:52:22+00:00" }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "1.0", @@ -267,22 +376,22 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.1.1", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/46f7e8bb075036c92695b15a1ddb6971c751e585", + "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585", "shasum": "" }, "require": { "php": ">=5.5", "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.2.0", + "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { @@ -308,24 +417,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-09-30T07:12:33+00:00" + "time": "2017-07-15T11:38:20+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.2.1", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "" }, "require": { - "php": ">=5.5", + "php": "^5.5 || ^7.0", "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { @@ -355,7 +464,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-11-25T06:54:22+00:00" + "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", @@ -422,40 +531,41 @@ }, { "name": "phpunit/php-code-coverage", - "version": "4.0.8", + "version": "5.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/dc421f9ca5082a0c0cb04afb171c765f79add85b", + "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^5.6 || ^7.0", + "php": "^7.0", "phpunit/php-file-iterator": "^1.3", "phpunit/php-text-template": "^1.2", - "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "phpunit/php-token-stream": "^1.4.11 || ^2.0", "sebastian/code-unit-reverse-lookup": "^1.0", - "sebastian/environment": "^1.3.2 || ^2.0", - "sebastian/version": "^1.0 || ^2.0" + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0", + "theseer/tokenizer": "^1.1" }, "require-dev": { - "ext-xdebug": "^2.1.4", - "phpunit/phpunit": "^5.7" + "ext-xdebug": "^2.5", + "phpunit/phpunit": "^6.0" }, "suggest": { - "ext-xdebug": "^2.5.1" + "ext-xdebug": "^2.5.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "5.2.x-dev" } }, "autoload": { @@ -481,7 +591,7 @@ "testing", "xunit" ], - "time": "2017-04-02T07:44:40+00:00" + "time": "2017-04-21T08:03:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -671,16 +781,16 @@ }, { "name": "phpunit/phpunit", - "version": "5.7.19", + "version": "6.2.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "69c4f49ff376af2692bad9cebd883d17ebaa98a1" + "reference": "fa5711d0559fc4b64deba0702be52d41434cbcb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/69c4f49ff376af2692bad9cebd883d17ebaa98a1", - "reference": "69c4f49ff376af2692bad9cebd883d17ebaa98a1", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fa5711d0559fc4b64deba0702be52d41434cbcb7", + "reference": "fa5711d0559fc4b64deba0702be52d41434cbcb7", "shasum": "" }, "require": { @@ -689,33 +799,35 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "~1.3", - "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.6.2", - "phpunit/php-code-coverage": "^4.0.4", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", + "myclabs/deep-copy": "^1.3", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.2", + "phpunit/php-file-iterator": "^1.4", + "phpunit/php-text-template": "^1.2", "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "^1.2.4", - "sebastian/diff": "~1.2", - "sebastian/environment": "^1.3.4 || ^2.0", - "sebastian/exporter": "~2.0", - "sebastian/global-state": "^1.1", - "sebastian/object-enumerator": "~2.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "~1.0.3|~2.0", - "symfony/yaml": "~2.1|~3.0" + "phpunit/phpunit-mock-objects": "^4.0", + "sebastian/comparator": "^2.0", + "sebastian/diff": "^1.4.3 || ^2.0", + "sebastian/environment": "^3.0.2", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^1.1 || ^2.0", + "sebastian/object-enumerator": "^3.0.2", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0" }, "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2" + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-xdebug": "*", - "phpunit/php-invoker": "~1.1" + "phpunit/php-invoker": "^1.1" }, "bin": [ "phpunit" @@ -723,7 +835,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.7.x-dev" + "dev-master": "6.2.x-dev" } }, "autoload": { @@ -749,33 +861,33 @@ "testing", "xunit" ], - "time": "2017-04-03T02:22:27+00:00" + "time": "2017-07-03T15:54:24+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.4.3", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" + "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", - "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4", + "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "php": "^5.6 || ^7.0", + "php": "^7.0", "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2 || ^2.0" + "sebastian/exporter": "^3.0" }, "conflict": { - "phpunit/phpunit": "<5.4.0" + "phpunit/phpunit": "<6.0" }, "require-dev": { - "phpunit/phpunit": "^5.4" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-soap": "*" @@ -783,7 +895,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "4.0.x-dev" } }, "autoload": { @@ -808,7 +920,7 @@ "mock", "xunit" ], - "time": "2016-12-08T20:27:08+00:00" + "time": "2017-06-30T08:15:21+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -857,30 +969,30 @@ }, { "name": "sebastian/comparator", - "version": "1.2.4", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "reference": "20f84f468cb67efee293246e6a09619b891f55f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0", + "reference": "20f84f468cb67efee293246e6a09619b891f55f0", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" + "php": "^7.0", + "sebastian/diff": "^1.2", + "sebastian/exporter": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -917,27 +1029,27 @@ "compare", "equality" ], - "time": "2017-01-29T09:50:25+00:00" + "time": "2017-03-03T06:26:08+00:00" }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", "extra": { @@ -969,32 +1081,32 @@ "keywords": [ "diff" ], - "time": "2015-12-08T07:14:41+00:00" + "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", - "version": "2.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1019,34 +1131,34 @@ "environment", "hhvm" ], - "time": "2016-11-26T07:53:53+00:00" + "time": "2017-07-01T08:51:00+00:00" }, { "name": "sebastian/exporter", - "version": "2.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~2.0" + "php": "^7.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1086,27 +1198,27 @@ "export", "exporter" ], - "time": "2016-11-19T08:54:04+00:00" + "time": "2017-04-03T13:19:02+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" @@ -1114,7 +1226,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1137,33 +1249,34 @@ "keywords": [ "global state" ], - "time": "2015-10-12T03:26:01+00:00" + "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/31dd3379d16446c5d86dec32ab1ad1f378581ad8", + "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/recursion-context": "~2.0" + "php": "^7.0", + "sebastian/object-reflector": "^1.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1183,32 +1296,77 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-02-18T15:18:39+00:00" + "time": "2017-03-12T15:17:29+00:00" }, { - "name": "sebastian/recursion-context", - "version": "2.0.0", + "name": "sebastian/object-reflector", + "version": "1.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1236,7 +1394,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-11-19T07:33:16+00:00" + "time": "2017-03-03T06:23:57+00:00" }, { "name": "sebastian/resource-operations", @@ -1325,16 +1483,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "2.7.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed" + "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", - "reference": "571e27b6348e5b3a637b2abc82ac0d01e6d7bbed", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62", + "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62", "shasum": "" }, "require": { @@ -1399,62 +1557,47 @@ "phpcs", "standards" ], - "time": "2016-09-01T23:53:02+00:00" + "time": "2017-05-22T02:43:20+00:00" }, { - "name": "symfony/yaml", - "version": "v3.2.7", + "name": "theseer/tokenizer", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621" + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/62b4cdb99d52cb1ff253c465eb1532a80cebb621", - "reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", "shasum": "" }, "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "symfony/console": "~2.8|~3.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2017-03-20T09:45:15+00:00" + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" }, { "name": "webmozart/assert", diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index 1e3b68851d0..3c2a13a3ca7 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -12,7 +12,7 @@ if [ $1 == 'before' ]; then if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then composer global require "phpunit/phpunit=4.8.*" else - composer global require "phpunit/phpunit=5.7.*" + composer global require "phpunit/phpunit=6.2.*" fi composer self-update From 84be2dd6bbdf65439f115ed0c108be8f871ad22e Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 13:32:47 -0300 Subject: [PATCH 051/127] Fixed declaration of WC_Tests_CRUD_Data::onNotSuccessfulTest --- tests/unit-tests/crud/data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit-tests/crud/data.php b/tests/unit-tests/crud/data.php index 9b38b26c63d..a3f9c425429 100644 --- a/tests/unit-tests/crud/data.php +++ b/tests/unit-tests/crud/data.php @@ -18,7 +18,7 @@ class WC_Tests_CRUD_Data extends WC_Unit_Test_Case { update_option( 'timezone_string', '' ); } - public function onNotSuccessfulTest( $e ) { + public function onNotSuccessfulTest( Throwable $e ) { // @codingStandardsIgnoreStart date_default_timezone_set( 'UTC' ); // @codingStandardsIgnoreEnd From 498a5daa53615bc502da75133ee5033f7479b755 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 13:34:34 -0300 Subject: [PATCH 052/127] Removed PHPCS from Travis in favor of pre-commit hook --- tests/bin/travis.sh | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index 3c2a13a3ca7..d57a67be39b 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -20,25 +20,7 @@ if [ $1 == 'before' ]; then elif [ $1 == 'after' ]; then - ## Only run on latest stable PHP box (defined in .travis.yml). - if [[ ${TRAVIS_PHP_VERSION} == ${PHP_LATEST_STABLE} ]]; then - # WordPress Coding Standards. - # @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards - # @link http://pear.php.net/package/PHP_CodeSniffer/ - # -p flag: Show progress of the run. - # -s flag: Show sniff codes in all reports. - # -v flag: Print verbose output. - # -n flag: Do not print warnings. (shortcut for --warning-severity=0) - # --standard: Use WordPress as the standard. - # --extensions: Only sniff PHP files. - ./vendor/bin/phpcs -p -s -n ./*.php --standard=./phpcs.ruleset.xml --extensions=php - ./vendor/bin/phpcs -p -s -n ./**/*.php --standard=./phpcs.ruleset.xml --extensions=php --ignore=./vendor/*.php --ignore=./tests/*.php - ./vendor/bin/phpcs -p -s -n ./**/**/*.php --standard=./phpcs.ruleset.xml --extensions=php --ignore=./vendor/**/*.php --ignore=./tests/**/*.php - ./vendor/bin/phpcs -p -s -n ./**/**/**/*.php --standard=./phpcs.ruleset.xml --extensions=php --ignore=./vendor/**/**/*.php --ignore=./tests/**/**/*.php - ./vendor/bin/phpcs -p -s -n ./**/**/**/**/*.php --standard=./phpcs.ruleset.xml --extensions=php --ignore=./vendor/**/**/*.php --ignore=./tests/**/**/*.php - fi - - ## Only run on master, not pull requests, latest stable PHP box (defined in .travis.yml). + # Only run on master, not pull requests, latest stable PHP box (defined in .travis.yml). if [[ ${TRAVIS_BRANCH} == 'master' ]] && [[ ${TRAVIS_EVENT_TYPE} != 'pull_request' ]] && [[ ${TRAVIS_PHP_VERSION} == ${PHP_LATEST_STABLE} ]]; then wget https://scrutinizer-ci.com/ocular.phar chmod +x ocular.phar From 5a918b8f93f4e4e08df7d53fca6e2d02f677538c Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 13:47:02 -0300 Subject: [PATCH 053/127] Not install project composer file on Travis --- tests/bin/travis.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index d57a67be39b..b548987e982 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -15,9 +15,6 @@ if [ $1 == 'before' ]; then composer global require "phpunit/phpunit=6.2.*" fi - composer self-update - composer install --no-interaction - elif [ $1 == 'after' ]; then # Only run on master, not pull requests, latest stable PHP box (defined in .travis.yml). From 46d3638089b58b51a2321b67443b83f409c6b4ec Mon Sep 17 00:00:00 2001 From: Jaydeep Rami Date: Thu, 20 Jul 2017 22:31:14 +0530 Subject: [PATCH 054/127] Fix missing return statement (#16148) * Fix missing return statement * Fix missing return statement * Fix missing return statement * Fix missing return statement * Fix missing return statement * Fix missing return statement --- includes/abstracts/abstract-wc-data.php | 2 +- includes/abstracts/abstract-wc-product.php | 3 ++- includes/abstracts/abstract-wc-settings-api.php | 1 - includes/abstracts/abstract-wc-widget.php | 5 +---- includes/admin/class-wc-admin-settings.php | 1 - includes/admin/class-wc-admin.php | 2 -- includes/admin/reports/class-wc-admin-report.php | 2 -- includes/admin/reports/class-wc-report-coupon-usage.php | 2 -- .../admin/reports/class-wc-report-sales-by-category.php | 2 -- includes/admin/reports/class-wc-report-sales-by-date.php | 2 -- includes/admin/reports/class-wc-report-sales-by-product.php | 2 -- includes/admin/reports/class-wc-report-taxes-by-code.php | 2 -- includes/admin/reports/class-wc-report-taxes-by-date.php | 2 -- includes/api/legacy/v1/class-wc-api-authentication.php | 1 - includes/api/legacy/v1/class-wc-api-customers.php | 1 - includes/api/legacy/v1/class-wc-api-resource.php | 1 - includes/api/legacy/v1/class-wc-api-server.php | 1 - includes/api/legacy/v2/class-wc-api-authentication.php | 1 - includes/api/legacy/v2/class-wc-api-customers.php | 1 - includes/api/legacy/v2/class-wc-api-resource.php | 1 - includes/api/legacy/v2/class-wc-api-server.php | 1 - includes/api/legacy/v3/class-wc-api-authentication.php | 1 - includes/api/legacy/v3/class-wc-api-customers.php | 1 - includes/api/legacy/v3/class-wc-api-resource.php | 1 - includes/api/legacy/v3/class-wc-api-server.php | 1 - includes/class-wc-emails.php | 5 ++--- includes/class-wc-tax.php | 4 ---- includes/data-stores/class-wc-data-store-wp.php | 1 - .../class-wc-addons-gateway-simplify-commerce.php | 1 - includes/import/abstract-wc-product-importer.php | 1 - includes/import/class-wc-product-csv-importer.php | 6 ------ .../class-wc-shipping-legacy-free-shipping.php | 1 - includes/wc-cart-functions.php | 1 - includes/wc-update-functions.php | 2 -- 34 files changed, 6 insertions(+), 56 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index fd4605b04fc..f1ec28fabe4 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -200,8 +200,8 @@ abstract class WC_Data { } else { $this->data_store->create( $this ); } - return $this->get_id(); } + return $this->get_id(); } /** diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php index eefd9527897..cdec7844dcf 100644 --- a/includes/abstracts/abstract-wc-product.php +++ b/includes/abstracts/abstract-wc-product.php @@ -1280,6 +1280,7 @@ class WC_Product extends WC_Abstract_Legacy_Product { * Save data (either create or update depending on if we are working on an existing product). * * @since 3.0.0 + * @return int */ public function save() { $this->validate_props(); @@ -1296,8 +1297,8 @@ class WC_Product extends WC_Abstract_Legacy_Product { if ( $this->get_parent_id() ) { wc_deferred_product_sync( $this->get_parent_id() ); } - return $this->get_id(); } + return $this->get_id(); } /* diff --git a/includes/abstracts/abstract-wc-settings-api.php b/includes/abstracts/abstract-wc-settings-api.php index ef4767fda4d..d96513a16bc 100644 --- a/includes/abstracts/abstract-wc-settings-api.php +++ b/includes/abstracts/abstract-wc-settings-api.php @@ -89,7 +89,6 @@ abstract class WC_Settings_API { * on the gateway's settings screen. * * @since 1.0.0 - * @return string */ public function init_form_fields() {} diff --git a/includes/abstracts/abstract-wc-widget.php b/includes/abstracts/abstract-wc-widget.php index 68b047c9b8c..8247a4d851b 100644 --- a/includes/abstracts/abstract-wc-widget.php +++ b/includes/abstracts/abstract-wc-widget.php @@ -118,10 +118,8 @@ abstract class WC_Widget extends WP_Widget { /** * Output the html at the start of a widget. * - * @param array $args + * @param array $args * @param array $instance - * - * @return string */ public function widget_start( $args, $instance ) { echo $args['before_widget']; @@ -135,7 +133,6 @@ abstract class WC_Widget extends WP_Widget { * Output the html at the end of a widget. * * @param array $args - * @return string */ public function widget_end( $args ) { echo $args['after_widget']; diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index 73bb749f5c1..e8fb57e0204 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -110,7 +110,6 @@ class WC_Admin_Settings { /** * Output messages + errors. - * @return string */ public static function show_messages() { if ( sizeof( self::$errors ) > 0 ) { diff --git a/includes/admin/class-wc-admin.php b/includes/admin/class-wc-admin.php index 1ca5210d75a..334590ea6f6 100644 --- a/includes/admin/class-wc-admin.php +++ b/includes/admin/class-wc-admin.php @@ -176,8 +176,6 @@ class WC_Admin { /** * Preview email template. - * - * @return string */ public function preview_emails() { diff --git a/includes/admin/reports/class-wc-admin-report.php b/includes/admin/reports/class-wc-admin-report.php index 9499cc832f4..b634b8c7a0e 100644 --- a/includes/admin/reports/class-wc-admin-report.php +++ b/includes/admin/reports/class-wc-admin-report.php @@ -616,8 +616,6 @@ class WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() {} diff --git a/includes/admin/reports/class-wc-report-coupon-usage.php b/includes/admin/reports/class-wc-report-coupon-usage.php index 2df70e25fb8..7e8a72ec7a0 100644 --- a/includes/admin/reports/class-wc-report-coupon-usage.php +++ b/includes/admin/reports/class-wc-report-coupon-usage.php @@ -359,8 +359,6 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() { global $wp_locale; diff --git a/includes/admin/reports/class-wc-report-sales-by-category.php b/includes/admin/reports/class-wc-report-sales-by-category.php index 390a6b22210..85f7d876806 100644 --- a/includes/admin/reports/class-wc-report-sales-by-category.php +++ b/includes/admin/reports/class-wc-report-sales-by-category.php @@ -272,8 +272,6 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() { global $wp_locale; diff --git a/includes/admin/reports/class-wc-report-sales-by-date.php b/includes/admin/reports/class-wc-report-sales-by-date.php index af72e510f12..7921dc61d26 100644 --- a/includes/admin/reports/class-wc-report-sales-by-date.php +++ b/includes/admin/reports/class-wc-report-sales-by-date.php @@ -607,8 +607,6 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() { global $wp_locale; diff --git a/includes/admin/reports/class-wc-report-sales-by-product.php b/includes/admin/reports/class-wc-report-sales-by-product.php index 95858057158..e5edd1a0769 100644 --- a/includes/admin/reports/class-wc-report-sales-by-product.php +++ b/includes/admin/reports/class-wc-report-sales-by-product.php @@ -387,8 +387,6 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() { global $wp_locale; diff --git a/includes/admin/reports/class-wc-report-taxes-by-code.php b/includes/admin/reports/class-wc-report-taxes-by-code.php index 7950e3bb002..8f488ea5c29 100644 --- a/includes/admin/reports/class-wc-report-taxes-by-code.php +++ b/includes/admin/reports/class-wc-report-taxes-by-code.php @@ -67,8 +67,6 @@ class WC_Report_Taxes_By_Code extends WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() { global $wpdb; diff --git a/includes/admin/reports/class-wc-report-taxes-by-date.php b/includes/admin/reports/class-wc-report-taxes-by-date.php index 2ffa0ea864e..6ac7424d092 100644 --- a/includes/admin/reports/class-wc-report-taxes-by-date.php +++ b/includes/admin/reports/class-wc-report-taxes-by-date.php @@ -67,8 +67,6 @@ class WC_Report_Taxes_By_Date extends WC_Admin_Report { /** * Get the main chart. - * - * @return string */ public function get_main_chart() { $query_data = array( diff --git a/includes/api/legacy/v1/class-wc-api-authentication.php b/includes/api/legacy/v1/class-wc-api-authentication.php index 87e79f3de92..1d26ae80ff6 100644 --- a/includes/api/legacy/v1/class-wc-api-authentication.php +++ b/includes/api/legacy/v1/class-wc-api-authentication.php @@ -19,7 +19,6 @@ class WC_API_Authentication { * Setup class * * @since 2.1 - * @return WC_API_Authentication */ public function __construct() { diff --git a/includes/api/legacy/v1/class-wc-api-customers.php b/includes/api/legacy/v1/class-wc-api-customers.php index d1b8fac6272..d5edb1503a2 100644 --- a/includes/api/legacy/v1/class-wc-api-customers.php +++ b/includes/api/legacy/v1/class-wc-api-customers.php @@ -31,7 +31,6 @@ class WC_API_Customers extends WC_API_Resource { * * @since 2.1 * @param WC_API_Server $server - * @return WC_API_Customers */ public function __construct( WC_API_Server $server ) { diff --git a/includes/api/legacy/v1/class-wc-api-resource.php b/includes/api/legacy/v1/class-wc-api-resource.php index c298e47a078..d419f8346e9 100644 --- a/includes/api/legacy/v1/class-wc-api-resource.php +++ b/includes/api/legacy/v1/class-wc-api-resource.php @@ -28,7 +28,6 @@ class WC_API_Resource { * * @since 2.1 * @param WC_API_Server $server - * @return WC_API_Resource */ public function __construct( WC_API_Server $server ) { diff --git a/includes/api/legacy/v1/class-wc-api-server.php b/includes/api/legacy/v1/class-wc-api-server.php index 6c85fcf4ade..530c6324def 100644 --- a/includes/api/legacy/v1/class-wc-api-server.php +++ b/includes/api/legacy/v1/class-wc-api-server.php @@ -112,7 +112,6 @@ class WC_API_Server { * * @since 2.1 * @param $path - * @return WC_API_Server */ public function __construct( $path ) { diff --git a/includes/api/legacy/v2/class-wc-api-authentication.php b/includes/api/legacy/v2/class-wc-api-authentication.php index 52b619a59c7..2c75a75b605 100644 --- a/includes/api/legacy/v2/class-wc-api-authentication.php +++ b/includes/api/legacy/v2/class-wc-api-authentication.php @@ -19,7 +19,6 @@ class WC_API_Authentication { * Setup class * * @since 2.1 - * @return WC_API_Authentication */ public function __construct() { diff --git a/includes/api/legacy/v2/class-wc-api-customers.php b/includes/api/legacy/v2/class-wc-api-customers.php index df92232aea6..d88865b1921 100644 --- a/includes/api/legacy/v2/class-wc-api-customers.php +++ b/includes/api/legacy/v2/class-wc-api-customers.php @@ -30,7 +30,6 @@ class WC_API_Customers extends WC_API_Resource { * * @since 2.1 * @param WC_API_Server $server - * @return WC_API_Customers */ public function __construct( WC_API_Server $server ) { diff --git a/includes/api/legacy/v2/class-wc-api-resource.php b/includes/api/legacy/v2/class-wc-api-resource.php index 89c3feef0fd..cd2a9ecde6f 100644 --- a/includes/api/legacy/v2/class-wc-api-resource.php +++ b/includes/api/legacy/v2/class-wc-api-resource.php @@ -27,7 +27,6 @@ class WC_API_Resource { * * @since 2.1 * @param WC_API_Server $server - * @return WC_API_Resource */ public function __construct( WC_API_Server $server ) { diff --git a/includes/api/legacy/v2/class-wc-api-server.php b/includes/api/legacy/v2/class-wc-api-server.php index e6413dca5ce..e5d43928193 100644 --- a/includes/api/legacy/v2/class-wc-api-server.php +++ b/includes/api/legacy/v2/class-wc-api-server.php @@ -111,7 +111,6 @@ class WC_API_Server { * * @since 2.1 * @param $path - * @return WC_API_Server */ public function __construct( $path ) { diff --git a/includes/api/legacy/v3/class-wc-api-authentication.php b/includes/api/legacy/v3/class-wc-api-authentication.php index 74c456309fd..88f0a711644 100644 --- a/includes/api/legacy/v3/class-wc-api-authentication.php +++ b/includes/api/legacy/v3/class-wc-api-authentication.php @@ -19,7 +19,6 @@ class WC_API_Authentication { * Setup class * * @since 2.1 - * @return WC_API_Authentication */ public function __construct() { diff --git a/includes/api/legacy/v3/class-wc-api-customers.php b/includes/api/legacy/v3/class-wc-api-customers.php index 4beca31c239..3ae5025530b 100644 --- a/includes/api/legacy/v3/class-wc-api-customers.php +++ b/includes/api/legacy/v3/class-wc-api-customers.php @@ -30,7 +30,6 @@ class WC_API_Customers extends WC_API_Resource { * * @since 2.1 * @param WC_API_Server $server - * @return WC_API_Customers */ public function __construct( WC_API_Server $server ) { diff --git a/includes/api/legacy/v3/class-wc-api-resource.php b/includes/api/legacy/v3/class-wc-api-resource.php index 4fefab1d0fb..4aface69c0c 100644 --- a/includes/api/legacy/v3/class-wc-api-resource.php +++ b/includes/api/legacy/v3/class-wc-api-resource.php @@ -27,7 +27,6 @@ class WC_API_Resource { * * @since 2.1 * @param WC_API_Server $server - * @return WC_API_Resource */ public function __construct( WC_API_Server $server ) { diff --git a/includes/api/legacy/v3/class-wc-api-server.php b/includes/api/legacy/v3/class-wc-api-server.php index 2e8aaaa6435..76cff49addf 100644 --- a/includes/api/legacy/v3/class-wc-api-server.php +++ b/includes/api/legacy/v3/class-wc-api-server.php @@ -111,7 +111,6 @@ class WC_API_Server { * * @since 2.1 * @param $path - * @return WC_API_Server */ public function __construct( $path ) { diff --git a/includes/class-wc-emails.php b/includes/class-wc-emails.php index b11928cce9e..8edc2d02660 100644 --- a/includes/class-wc-emails.php +++ b/includes/class-wc-emails.php @@ -375,9 +375,8 @@ class WC_Emails { * Add order meta to email templates. * * @param mixed $order - * @param bool $sent_to_admin (default: false) - * @param bool $plain_text (default: false) - * @return string + * @param bool $sent_to_admin (default: false) + * @param bool $plain_text (default: false) */ public function order_meta( $order, $sent_to_admin = false, $plain_text = false ) { $fields = apply_filters( 'woocommerce_email_order_meta_fields', array(), $sent_to_admin, $order ); diff --git a/includes/class-wc-tax.php b/includes/class-wc-tax.php index 7132f694eb4..a0c72452db3 100644 --- a/includes/class-wc-tax.php +++ b/includes/class-wc-tax.php @@ -916,7 +916,6 @@ class WC_Tax { * * @param int $tax_rate_id * @param string $postcodes String of postcodes separated by ; characters - * @return string */ public static function _update_tax_rate_postcodes( $tax_rate_id, $postcodes ) { if ( ! is_array( $postcodes ) ) { @@ -939,7 +938,6 @@ class WC_Tax { * * @param int $tax_rate_id * @param string $cities - * @return string */ public static function _update_tax_rate_cities( $tax_rate_id, $cities ) { if ( ! is_array( $cities ) ) { @@ -961,8 +959,6 @@ class WC_Tax { * @param int $tax_rate_id * @param array $values * @param string $type - * - * @return string */ private static function _update_tax_rate_locations( $tax_rate_id, $values, $type ) { global $wpdb; diff --git a/includes/data-stores/class-wc-data-store-wp.php b/includes/data-stores/class-wc-data-store-wp.php index 241275bc7c6..41e427c857d 100644 --- a/includes/data-stores/class-wc-data-store-wp.php +++ b/includes/data-stores/class-wc-data-store-wp.php @@ -86,7 +86,6 @@ class WC_Data_Store_WP { * @since 3.0.0 * @param WC_Data * @param stdClass (containing at least ->id) - * @return array */ public function delete_meta( &$object, $meta ) { delete_metadata_by_mid( $this->meta_type, $meta->id ); diff --git a/includes/gateways/simplify-commerce/class-wc-addons-gateway-simplify-commerce.php b/includes/gateways/simplify-commerce/class-wc-addons-gateway-simplify-commerce.php index 396bfd9d530..ea3b58d0bec 100644 --- a/includes/gateways/simplify-commerce/class-wc-addons-gateway-simplify-commerce.php +++ b/includes/gateways/simplify-commerce/class-wc-addons-gateway-simplify-commerce.php @@ -393,7 +393,6 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce { * @since 2.4 * @param string $payment_method_id The ID of the payment method to validate * @param array $payment_meta associative array of meta data required for automatic payments - * @return array * @throws Exception */ public function validate_subscription_payment_meta( $payment_method_id, $payment_meta ) { diff --git a/includes/import/abstract-wc-product-importer.php b/includes/import/abstract-wc-product-importer.php index b1684c41dbc..251139d29fa 100644 --- a/includes/import/abstract-wc-product-importer.php +++ b/includes/import/abstract-wc-product-importer.php @@ -293,7 +293,6 @@ abstract class WC_Product_Importer implements WC_Importer_Interface { * @param WC_Product $product Product instance. * @param array $data Item data. * - * @return WC_Product|WP_Error * @throws Exception */ protected function set_product_data( &$product, $data ) { diff --git a/includes/import/class-wc-product-csv-importer.php b/includes/import/class-wc-product-csv-importer.php index 8ac995e10c0..aa69148a32e 100644 --- a/includes/import/class-wc-product-csv-importer.php +++ b/includes/import/class-wc-product-csv-importer.php @@ -54,8 +54,6 @@ class WC_Product_CSV_Importer extends WC_Product_Importer { /** * Read file. - * - * @return array */ protected function read_file() { if ( false !== ( $handle = fopen( $this->file, 'r' ) ) ) { @@ -107,8 +105,6 @@ class WC_Product_CSV_Importer extends WC_Product_Importer { /** * Set file mapped keys. - * - * @return array */ protected function set_mapped_keys() { $mapping = $this->params['mapping']; @@ -668,8 +664,6 @@ class WC_Product_CSV_Importer extends WC_Product_Importer { /** * Map and format raw data to known fields. - * - * @return array */ protected function set_parsed_data() { $parse_functions = $this->get_formating_callback(); diff --git a/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php b/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php index dd2170f2d91..be23051a1fa 100644 --- a/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php +++ b/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php @@ -216,7 +216,6 @@ class WC_Shipping_Legacy_Free_Shipping extends WC_Shipping_Method { /** * calculate_shipping function. - * @return array */ public function calculate_shipping( $package = array() ) { $args = array( diff --git a/includes/wc-cart-functions.php b/includes/wc-cart-functions.php index 2f69aa152b9..8eb336c7717 100644 --- a/includes/wc-cart-functions.php +++ b/includes/wc-cart-functions.php @@ -191,7 +191,6 @@ add_action( 'get_header', 'wc_clear_cart_after_payment' ); * Get the subtotal. * * @access public - * @return string */ function wc_cart_totals_subtotal_html() { echo WC()->cart->get_cart_subtotal(); diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 6cdef46a8b3..250c07c4c70 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -995,8 +995,6 @@ function wc_update_300_webhooks() { /** * Add an index to the field comment_type to improve the response time of the query * used by WC_Comments::wp_count_comments() to get the number of comments by type. - * - * @return null */ function wc_update_300_comment_type_index() { global $wpdb; From 383c7eb8895f74c89969aaf3aea41e661d90e859 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 15:48:56 -0300 Subject: [PATCH 055/127] Fixed excluded paths for Code Climate --- .codeclimate.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 87f5413334f..707dca03ece 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -15,24 +15,24 @@ engines: - javascript ratings: paths: - - "includes/*" + - "includes/*" exclude_paths: - - tests/* - - apigen/* - - dummy-data/* - - i18n/* - - includes/api/legacy/* - - includes/libraries/* - - includes/updates/* - - includes/gateways/simplify-commerce/* - - includes/shipping/legacy-* - - includes/wc-deprecated-functions.php - - includes/class-wc-legacy-api.php - - assets/js/accounting/** - - assets/js/jquery-* - - assets/js/prettyPhoto/* - - assets/js/round/* - - assets/js/select2/* - - assets/js/selectWoo/* - - assets/js/stupidtable/* - - assets/js/zeroclipboard/* +- "tests/" +- "apigen/" +- "dummy-data/" +- "i18n/" +- "includes/api/legacy/" +- "includes/libraries/" +- "includes/updates/" +- "includes/gateways/simplify-commerce/" +- "includes/shipping/legacy-*" +- "includes/wc-deprecated-functions.php" +- "includes/class-wc-legacy-api.php" +- "assets/js/accounting/" +- "assets/js/jquery-*" +- "assets/js/prettyPhoto/" +- "assets/js/round/" +- "assets/js/select2/" +- "assets/js/selectWoo/" +- "assets/js/stupidtable/" +- "assets/js/zeroclipboard/" From 4251bd56143ca1188aeb8dca3c4ff8c471bb99da Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 16:50:12 -0300 Subject: [PATCH 056/127] Move code coverage to Scrutinizer --- .coveralls.yml | 3 --- .scrutinizer.yml | 23 +++++++++++++++++++++-- .travis.yml | 2 +- tests/bin/phpunit.sh | 5 ----- tests/bin/travis.sh | 9 --------- 5 files changed, 22 insertions(+), 20 deletions(-) delete mode 100644 .coveralls.yml delete mode 100755 tests/bin/phpunit.sh diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index c00a1ca9322..00000000000 --- a/.coveralls.yml +++ /dev/null @@ -1,3 +0,0 @@ -src_dir: . -coverage_clover: ./tmp/clover.xml -json_path: ./tmp/coveralls-upload.json diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 543a40cf4ed..9e2c1c000a3 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -30,5 +30,24 @@ checks: tools: sensiolabs_security_checker: true - external_code_coverage: - timeout: 600 # Wait 10 minutes for Travis send coverage file. + +build: + environment: + php: '7.1' + mysql: true + apache2: + modules: ['rewrite'] + variables: + WP_VERSION: 'latest' + dependencies: + before: + - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + - curl -sS https://getcomposer.org/installer | php + - php composer.phar install + tests: + override: + - + command: 'vendor/bin/phpunit --coverage-clover=results' + coverage: + file: 'results' + format: 'clover' diff --git a/.travis.yml b/.travis.yml index bc49cf91d6e..3733acf8f38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ before_script: - bash tests/bin/travis.sh before script: - - bash tests/bin/phpunit.sh + - phpunit -c phpunit.xml.dist after_script: - bash tests/bin/travis.sh after diff --git a/tests/bin/phpunit.sh b/tests/bin/phpunit.sh deleted file mode 100755 index bb7a731ab40..00000000000 --- a/tests/bin/phpunit.sh +++ /dev/null @@ -1,5 +0,0 @@ -if [[ ${TRAVIS_BRANCH} == 'master' ]] && [[ ${TRAVIS_EVENT_TYPE} != 'pull_request' ]] && [[ ${TRAVIS_PHP_VERSION} == ${PHP_LATEST_STABLE} ]]; then - phpunit -c phpunit.xml.dist --coverage-clover ./tmp/clover.xml -else - phpunit -c phpunit.xml.dist -fi diff --git a/tests/bin/travis.sh b/tests/bin/travis.sh index b548987e982..b04b7973d34 100755 --- a/tests/bin/travis.sh +++ b/tests/bin/travis.sh @@ -15,13 +15,4 @@ if [ $1 == 'before' ]; then composer global require "phpunit/phpunit=6.2.*" fi -elif [ $1 == 'after' ]; then - - # Only run on master, not pull requests, latest stable PHP box (defined in .travis.yml). - if [[ ${TRAVIS_BRANCH} == 'master' ]] && [[ ${TRAVIS_EVENT_TYPE} != 'pull_request' ]] && [[ ${TRAVIS_PHP_VERSION} == ${PHP_LATEST_STABLE} ]]; then - wget https://scrutinizer-ci.com/ocular.phar - chmod +x ocular.phar - php ocular.phar code-coverage:upload --format=php-clover ./tmp/clover.xml - fi - fi From 814f1b228bb57a31a4728f46eacdff2b78bdc2f8 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 17:24:52 -0300 Subject: [PATCH 057/127] Allow WP CodeSniffer on Scrutinizer and improved environment settings --- .scrutinizer.yml | 78 +++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 9e2c1c000a3..0f8d23732e5 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,17 +1,30 @@ -filter: - excluded_paths: - - tests/* - - apigen/* - - dummy-data/* - - i18n/* - - includes/api/legacy/* - - includes/legacy/* - - includes/libraries/* - - includes/updates/* - - includes/gateways/simplify-commerce/* - - includes/shipping/legacy-* - - includes/wc-deprecated-functions.php - - includes/class-wc-legacy-api.php +build: + environment: + php: '7.1' + mysql: true + postgresql: false + redis: false + node: false + apache2: + modules: ['rewrite'] + variables: + WP_VERSION: 'latest' + dependencies: + before: + - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + tests: + override: + - + command: 'vendor/bin/phpunit --coverage-clover=results' + coverage: + file: 'results' + format: 'clover' + +tools: + sensiolabs_security_checker: true + php_code_sniffer: + config: + standard: "WordPress" checks: php: @@ -28,26 +41,17 @@ checks: avoid_superglobals: false avoid_closing_tag: false -tools: - sensiolabs_security_checker: true - -build: - environment: - php: '7.1' - mysql: true - apache2: - modules: ['rewrite'] - variables: - WP_VERSION: 'latest' - dependencies: - before: - - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - - curl -sS https://getcomposer.org/installer | php - - php composer.phar install - tests: - override: - - - command: 'vendor/bin/phpunit --coverage-clover=results' - coverage: - file: 'results' - format: 'clover' +filter: + excluded_paths: + - tests/* + - apigen/* + - dummy-data/* + - i18n/* + - includes/api/legacy/* + - includes/legacy/* + - includes/libraries/* + - includes/updates/* + - includes/gateways/simplify-commerce/* + - includes/shipping/legacy-* + - includes/wc-deprecated-functions.php + - includes/class-wc-legacy-api.php From dcbe09376feaa777fc69a2a23c1a4bafa79cea67 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 18:05:36 -0300 Subject: [PATCH 058/127] Enable WordPress standard on Scrutinizer --- .scrutinizer.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 0f8d23732e5..122bcea2155 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -4,7 +4,6 @@ build: mysql: true postgresql: false redis: false - node: false apache2: modules: ['rewrite'] variables: @@ -24,7 +23,7 @@ tools: sensiolabs_security_checker: true php_code_sniffer: config: - standard: "WordPress" + standard: WordPress checks: php: @@ -40,6 +39,8 @@ checks: no_exit: false avoid_superglobals: false avoid_closing_tag: false + coding_standard: + name: WordPress filter: excluded_paths: From cb3e1de0bec17bf340840960c0945c655aa5c9a8 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 20 Jul 2017 18:14:53 -0300 Subject: [PATCH 059/127] Fixed coding standards --- includes/emails/class-wc-email.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/emails/class-wc-email.php b/includes/emails/class-wc-email.php index 62795af8a17..8bcf0660e8f 100644 --- a/includes/emails/class-wc-email.php +++ b/includes/emails/class-wc-email.php @@ -213,7 +213,7 @@ class WC_Email extends WC_Settings_API { // Find/replace if ( empty( $this->placeholders ) ) { $this->placeholders = array( - '{site_title}' => $this->get_blogname() + '{site_title}' => $this->get_blogname(), ); } From 50dbef7e8e5ff3bfefef2cb22668fde602953af5 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 21 Jul 2017 00:28:49 -0300 Subject: [PATCH 060/127] Set phpunit.xml.dist file for tests in Scrutinizer --- .scrutinizer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 122bcea2155..f3ec5117a1b 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -14,7 +14,7 @@ build: tests: override: - - command: 'vendor/bin/phpunit --coverage-clover=results' + command: 'vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=results' coverage: file: 'results' format: 'clover' From e44450a40c2dc5cbdc52634bc59530dba47e69af Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 21 Jul 2017 10:39:24 +0100 Subject: [PATCH 061/127] Remove duplicate inherited method Closes #16206 --- includes/class-wc-product-variation.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/includes/class-wc-product-variation.php b/includes/class-wc-product-variation.php index f0c58de6f0a..79296d27b7d 100644 --- a/includes/class-wc-product-variation.php +++ b/includes/class-wc-product-variation.php @@ -426,16 +426,6 @@ class WC_Product_Variation extends WC_Product_Simple { $this->set_prop( 'attributes', $attributes ); } - /** - * Returns array of attribute name value pairs. Keys are prefixed with attribute_, as stored. - * - * @param string $context - * @return array - */ - public function get_attributes( $context = 'view' ) { - return $this->get_prop( 'attributes', $context ); - } - /** * Returns whether or not the product has any visible attributes. * From fd12c344f8b4bb4ace808bd6b94ca90d395c436c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 21 Jul 2017 11:11:17 +0100 Subject: [PATCH 062/127] Ensure we have a http URL for file path replacements Closes #16179 --- includes/class-wc-download-handler.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index 3f109521d7f..dfd9c8d99c2 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -189,13 +189,17 @@ class WC_Download_Handler { $wp_uploads_dir = $wp_uploads['basedir']; $wp_uploads_url = $wp_uploads['baseurl']; - // Replace uploads dir, site url etc with absolute counterparts if we can + /** + * Replace uploads dir, site url etc with absolute counterparts if we can. + * Note the str_replace on site_url is on purpose, so if https is forced + * via filters we can still do the string replacement on a HTTP file. + */ $replacements = array( - $wp_uploads_url => $wp_uploads_dir, - network_site_url( '/', 'https' ) => ABSPATH, - network_site_url( '/', 'http' ) => ABSPATH, - site_url( '/', 'https' ) => ABSPATH, - site_url( '/', 'http' ) => ABSPATH, + $wp_uploads_url => $wp_uploads_dir, + network_site_url( '/', 'https' ) => ABSPATH, + str_replace( 'https:', 'http:', network_site_url( '/', 'http' ) ) => ABSPATH, + site_url( '/', 'https' ) => ABSPATH, + str_replace( 'https:', 'http:', site_url( '/', 'http' ) ) => ABSPATH, ); $file_path = str_replace( array_keys( $replacements ), array_values( $replacements ), $file_path ); From 7c01201e3408c2ca278c30e4d0a43efefbf3b5fc Mon Sep 17 00:00:00 2001 From: Paul Robinson Date: Fri, 21 Jul 2017 14:23:21 +0100 Subject: [PATCH 063/127] Add custom attributes into radio fields for woocommerce_form_field --- .gitattributes | 1 + includes/wc-template-functions.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 5e8686b5f3a..522d014b522 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,3 +8,4 @@ phpcs.ruleset.xml export-ignore phpunit.* export-ignore README.md export-ignore tests export-ignore +* text eol=lf diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 51d8ed192d1..3eb519a97b5 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -2102,7 +2102,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) { if ( ! empty( $args['options'] ) ) { foreach ( $args['options'] as $option_key => $option_text ) { - $field .= ''; + $field .= ''; $field .= ''; } } From a82181f435a9b9f25fda618d4602e21ee2036bed Mon Sep 17 00:00:00 2001 From: Paul Robinson Date: Fri, 21 Jul 2017 14:24:53 +0100 Subject: [PATCH 064/127] reset gitattributes file --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 522d014b522..5e8686b5f3a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,4 +8,3 @@ phpcs.ruleset.xml export-ignore phpunit.* export-ignore README.md export-ignore tests export-ignore -* text eol=lf From c5055ed2f76a103d9bdbf1b0d46e1909db3bf0b5 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 21 Jul 2017 14:25:27 -0300 Subject: [PATCH 065/127] Tidy up Scrutinizer, PHPUnit and Travis config --- .scrutinizer.yml | 70 ++++++++++++++++++++++++------------------------ .travis.yml | 2 +- phpunit.xml | 7 +++-- phpunit.xml.dist | 40 --------------------------- 4 files changed, 39 insertions(+), 80 deletions(-) delete mode 100644 phpunit.xml.dist diff --git a/.scrutinizer.yml b/.scrutinizer.yml index f3ec5117a1b..0cf3c219ad0 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,58 +1,58 @@ build: environment: - php: '7.1' + php: "7.1" mysql: true postgresql: false redis: false apache2: - modules: ['rewrite'] + modules: + - rewrite variables: - WP_VERSION: 'latest' + WP_VERSION: latest dependencies: before: - - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + - "bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION" tests: override: - - - command: 'vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=results' - coverage: - file: 'results' - format: 'clover' - + - + command: "vendor/bin/phpunit -c phpunit.xml --coverage-clover=results" + coverage: + file: results + format: clover tools: - sensiolabs_security_checker: true php_code_sniffer: config: standard: WordPress - + sensiolabs_security_checker: true checks: php: + avoid_closing_tag: false + avoid_superglobals: false + coding_standard: + name: WordPress + no_exit: false + no_global_keyword: false + one_class_per_file: false + psr2_class_declaration: false + psr2_control_structure_declaration: false + psr2_switch_declaration: false variable_existence: false verify_access_scope_valid: false verify_argument_usable_as_reference: false verify_property_names: false - no_global_keyword: false - psr2_switch_declaration: false - psr2_control_structure_declaration: false - psr2_class_declaration: false - one_class_per_file: false - no_exit: false - avoid_superglobals: false - avoid_closing_tag: false - coding_standard: - name: WordPress - filter: excluded_paths: - - tests/* - - apigen/* - - dummy-data/* - - i18n/* - - includes/api/legacy/* - - includes/legacy/* - - includes/libraries/* - - includes/updates/* - - includes/gateways/simplify-commerce/* - - includes/shipping/legacy-* - - includes/wc-deprecated-functions.php - - includes/class-wc-legacy-api.php + - apigen/ + - dummy-data/ + - i18n/ + - includes/api/legacy/ + - includes/class-wc-legacy-api.php + - includes/gateways/simplify-commerce-deprecated/ + - includes/gateways/simplify-commerce/includes/ + - includes/legacy/ + - includes/libraries/ + - includes/shipping/legacy-* + - includes/updates/ + - includes/vendor/ + - includes/wc-deprecated-functions.php + - tests/ diff --git a/.travis.yml b/.travis.yml index 3733acf8f38..387f2e67ba1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ before_script: - bash tests/bin/travis.sh before script: - - phpunit -c phpunit.xml.dist + - phpunit -c phpunit.xml after_script: - bash tests/bin/travis.sh after diff --git a/phpunit.xml b/phpunit.xml index 0a829bc9242..f7c911553a9 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -30,14 +30,13 @@ ./includes/shipping/legacy-local-delivery/ ./includes/shipping/legacy-local-pickup/ ./includes/updates/ + ./includes/vendor/ ./includes/widgets/ ./templates/ - ./tests/ + ./tests/ ./tmp/ + ./vendor/ - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index 0ae53994749..00000000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,40 +0,0 @@ - - - - - ./tests/unit-tests - - - - - . - - ./apigen/ - ./i18n/ - ./includes/api/legacy/ - ./includes/gateways/simplify-commerce-deprecated/ - ./includes/gateways/simplify-commerce/includes/ - ./includes/libraries/ - ./includes/shipping/legacy-flat-rate/ - ./includes/shipping/legacy-free-shipping/ - ./includes/shipping/legacy-international-delivery/ - ./includes/shipping/legacy-local-delivery/ - ./includes/shipping/legacy-local-pickup/ - ./includes/updates/ - ./includes/widgets/ - ./templates/ - ./tests/ - ./tmp/ - - - - From 504a2165828c0e54ee6264a320e6d88671013a27 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jul 2017 10:43:34 +0100 Subject: [PATCH 066/127] Check data is an array in set_variation method Closes #16232 --- includes/class-wc-order-item-product.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index 2cf90dfb801..6a08d298170 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -165,9 +165,11 @@ class WC_Order_Item_Product extends WC_Order_Item { * * @param array $data Key/Value pairs */ - public function set_variation( $data ) { - foreach ( $data as $key => $value ) { - $this->add_meta_data( str_replace( 'attribute_', '', $key ), $value, true ); + public function set_variation( $data = array() ) { + if ( is_array( $data ) ) { + foreach ( $data as $key => $value ) { + $this->add_meta_data( str_replace( 'attribute_', '', $key ), $value, true ); + } } } From a9339f60d3b964c2b172a1371849cfa8ccbdd31c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jul 2017 13:23:38 +0100 Subject: [PATCH 067/127] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 82fafab64d4..691915e6086 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,35 +1,46 @@ + + + + + + + + ## Prerequisites - + - [ ] I have searched for similar issues in both open and closed tickets and cannot find a duplicate -- [ ] The issue still exists against the latest `master` branch of WooCommerce -- [ ] This is not a usage question (Those should be directed to the [community](https://wordpress.org/support/plugin/woocommerce), unless this is a question about a premium plugin in which you should [use the helpdesk](https://woocommerce.com/my-account/tickets/) for official extensions or contact the author of 3rd party extensions) +- [ ] The issue still exists against the latest `master` branch of WooCommerce on Github - [ ] I have attempted to find the simplest possible steps to reproduce the issue - [ ] I have included a failing test as a pull request (Optional) ## Steps to reproduce the issue + + 1. 2. 3. -## Expected behavior and actual behavior +## Expected/actual behavior When I follow those steps, I see... -I was expecting... - -## Environment - -
    -``` -Grab the system status report from WooCommerce > System Status and paste it here. -``` -
    +I was expecting to see... ## Isolating the problem + + - [ ] This bug happens with only WooCommerce plugin active - [ ] This bug happens with a default WordPress theme active, or [Storefront](https://woocommerce.com/storefront/) -- [ ] I can reproduce this bug consistently +- [ ] I can reproduce this bug consistently using the steps above + +## WordPress Environment + +
    +``` +Copy and paste the system status report from **WooCommerce > System Status** in WordPress admin here. +``` +
    From b376b548b9c74750bf11f0d36ee199dd507e57f8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jul 2017 13:25:23 +0100 Subject: [PATCH 068/127] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 691915e6086..518852e36a4 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -6,6 +6,8 @@ + + ## Prerequisites @@ -15,6 +17,8 @@ - [ ] I have attempted to find the simplest possible steps to reproduce the issue - [ ] I have included a failing test as a pull request (Optional) + + ## Steps to reproduce the issue @@ -23,12 +27,16 @@ 2. 3. + + ## Expected/actual behavior When I follow those steps, I see... I was expecting to see... + + ## Isolating the problem @@ -37,6 +45,8 @@ I was expecting to see... - [ ] This bug happens with a default WordPress theme active, or [Storefront](https://woocommerce.com/storefront/) - [ ] I can reproduce this bug consistently using the steps above + + ## WordPress Environment
    From 0b9b178522ceb94f64ca8b5d52a55c1d4fc5f04f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jul 2017 13:32:45 +0100 Subject: [PATCH 069/127] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 518852e36a4..1232b9d801f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,8 @@ - + - + From c9d500f4db6edcb5de7bfa4799823ff8a091a53a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jul 2017 13:34:04 +0100 Subject: [PATCH 070/127] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 1232b9d801f..673795380b0 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,6 @@ - + From cdbead8961930ea9984ff256bcea631100c125d6 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Mon, 24 Jul 2017 15:05:23 -0700 Subject: [PATCH 071/127] Clean up and tests --- includes/class-wc-product-query.php | 13 +- .../class-wc-product-data-store-cpt.php | 34 ++- tests/unit-tests/product/functions.php | 221 +++++++++++++++++- 3 files changed, 245 insertions(+), 23 deletions(-) diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php index 935e962bb4d..613cd3b51f5 100644 --- a/includes/class-wc-product-query.php +++ b/includes/class-wc-product-query.php @@ -26,13 +26,10 @@ class WC_Product_Query extends WC_Object_Query { 'type' => array_merge( array_keys( wc_get_product_types() ) ), 'limit' => get_option( 'posts_per_page' ), 'include' => array(), - 'slug' => '', 'date_created' => '', 'date_modified' => '', 'featured' => '', - 'catalog_visibility' => '', - 'description' => '', - 'short_description' => '', + 'visibility' => '', 'sku' => '', 'price' => '', 'regular_price' => '', @@ -51,22 +48,14 @@ class WC_Product_Query extends WC_Object_Query { 'length' => '', 'width' => '', 'height' => '', - 'upsell_ids' => array(), - 'cross_sell_ids' => array(), 'reviews_allowed' => '', - 'purchase_note' => '', - 'attributes' => array(), - 'default_attributes' => array(), - 'menu_order' => '', 'virtual' => '', 'downloadable' => '', 'category' => array(), 'tag' => array(), 'shipping_class' => array(), - 'image_id' => '', 'download_limit' => '', 'download_expiry' => '', - 'rating_counts' => array(), 'average_rating' => '', 'review_count' => '', ) diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 872e7c2614f..359ccca713d 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1273,7 +1273,6 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da 'page' => 'paged', 'include' => 'post__in', ); - foreach ( $key_mapping as $query_key => $db_key ) { if ( isset( $query_vars[ $query_key ] ) ) { $query_vars[ $db_key ] = $query_vars[ $query_key ]; @@ -1281,6 +1280,22 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da } } + // Map boolean queries that are stored as 'yes'/'no' in the DB. + $boolean_queries = array( + 'virtual', + 'downloadable', + 'featured', + 'sold_individually', + 'manage_stock', + 'reviews_allowed', + ); + foreach ( $boolean_queries as $boolean_query ) { + if ( isset( $query_vars[ $boolean_query ] ) && is_bool( $query_vars[ $boolean_query ] ) ) { + $query_vars[ $boolean_query ] = $query_vars[ $boolean_query ] ? 'yes' : 'no'; + } + } + + // SKU needs special handling because it works with partial matches. // Don't auto-generate meta query args for it. $sku_query = false; @@ -1289,6 +1304,14 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da unset( $query_vars['sku'] ); } + // total_sales needs special handline because the meta key doesn't have the underscore prefix. + // Don't auto generate meta query args for it. + $total_sales_query = false; + if ( isset( $query_vars['total_sales'] ) ) { + $total_sales_query = $query_vars['total_sales']; + unset( $query_vars['total_sales'] ); + } + $wp_query_args = parent::get_wp_query_args( $query_vars ); if ( ! isset( $wp_query_args['date_query'] ) ) { @@ -1307,6 +1330,15 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da ); } + // Manually build the total_sales query if needed. + if ( $total_sales_query ) { + $wp_query_args['meta_query'][] = array( + 'key' => 'total_sales', + 'value' => $total_sales_query, + 'compare' => '=', + ); + } + // Handle product types. if ( 'variation' === $query_vars['type'] ) { $wp_query_args['post_type'] = 'product_variation'; diff --git a/tests/unit-tests/product/functions.php b/tests/unit-tests/product/functions.php index 6fb6e38071b..9980f7c8dea 100644 --- a/tests/unit-tests/product/functions.php +++ b/tests/unit-tests/product/functions.php @@ -51,29 +51,33 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { $this->assertEquals( 9, count( wc_get_products( array( 'return' => 'ids' ) ) ) ); - // test status + // Test status. $products = wc_get_products( array( 'return' => 'ids', 'status' => 'draft' ) ); $this->assertEquals( array( $draft->get_id() ), $products ); - // test type + // Test type. $products = wc_get_products( array( 'return' => 'ids', 'type' => 'variation' ) ); $this->assertEquals( 2, count( $products ) ); - // test parent + // Test parent. $products = wc_get_products( array( 'return' => 'ids', 'type' => 'variation', 'parent' => $variation->get_id() ) ); $this->assertEquals( 2, count( $products ) ); - // test skus + // Test parent_exclude. + $products = wc_get_products( array( 'return' => 'ids', 'type' => 'variation', 'parent_exclude' => array( $variation->get_id() ) ) ); + $this->assertEquals( 0, count( $products ) ); + + // Test skus. $products = wc_get_products( array( 'return' => 'ids', 'sku' => 'GET TEST SKU' ) ); $this->assertEquals( 2, count( $products ) ); $this->assertContains( $product->get_id(), $products ); $this->assertContains( $external->get_id(), $products ); - // test categories + // Test categories. $products = wc_get_products( array( 'return' => 'ids', 'category' => array( $term_cat_1->slug ) ) ); $this->assertEquals( 3, count( $products ) ); - // test tags + // Test tags. $products = wc_get_products( array( 'return' => 'ids', 'tag' => array( $term_tag_1->slug ) ) ); $this->assertEquals( 2, count( $products ) ); @@ -83,31 +87,228 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { $products = wc_get_products( array( 'return' => 'ids', 'tag' => array( $term_tag_1->slug, $term_tag_2->slug ) ) ); $this->assertEquals( 3, count( $products ) ); - // test limit + // Test limit. $products = wc_get_products( array( 'return' => 'ids', 'limit' => 5 ) ); $this->assertEquals( 5, count( $products ) ); - // test offset + // Test offset. $products = wc_get_products( array( 'return' => 'ids', 'limit' => 2 ) ); $products_offset = wc_get_products( array( 'return' => 'ids', 'limit' => 2, 'offset' => 2 ) ); $this->assertEquals( 2, count( $products ) ); $this->assertEquals( 2, count( $products_offset ) ); $this->assertNotEquals( $products, $products_offset ); - // test page + // Test page. $products_page_1 = wc_get_products( array( 'return' => 'ids', 'limit' => 2 ) ); $products_page_2 = wc_get_products( array( 'return' => 'ids', 'limit' => 2, 'page' => 2 ) ); $this->assertEquals( 2, count( $products_page_1 ) ); $this->assertEquals( 2, count( $products_page_2 ) ); $this->assertNotEquals( $products_page_1, $products_page_2 ); - // test exclude + // Test exclude. $products = wc_get_products( array( 'return' => 'ids', 'limit' => 200, 'exclude' => array( $product->get_id() ) ) ); $this->assertNotContains( $product->get_id(), $products ); + // Test include. + $products = wc_get_products( array( 'return' => 'ids', 'include' => array( $product->get_id() ) ) ); + $this->assertContains( $product->get_id(), $products ); + + // Test order and orderby. + $products = wc_get_products( array( 'return' => 'ids', 'order' => 'ASC', 'orderby' => 'ID', 'limit' => 2 ) ); + $this->assertEquals( array( $product->get_id(), $product_2->get_id() ), $products ); + + // Test paginate. + $products = wc_get_products( array( 'paginate' => true ) ); + $this->assertGreaterThan( 0, $products->total ); + $this->assertGreaterThan( 0, $products->max_num_pages ); + $this->assertNotEmpty( $products->products ); + $variation->delete( true ); } + /** + * Tests wc_get_products() with dimension parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_dimensions() { + $product_1 = new WC_Product_Simple; + $product_1->set_width( '12.5' ); + $product_1->set_height( '5' ); + $product_1->set_weight( '11.4' ); + $product_1->save(); + + $product_2 = new WC_Product_Simple; + $product_2->set_width( '10' ); + $product_2->set_height( '5' ); + $product_2->set_weight( '15' ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'width' => 12.5 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'height' => 5.0 ) ); + $this->assertEquals( array( $product_1->get_id(), $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'weight' => 15 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + } + + /** + * Tests wc_get_products() with price parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_price() { + $product_1 = new WC_Product_Simple; + $product_1->set_regular_price( '12.5' ); + $product_1->set_price( '12.5' ); + $product_1->save(); + + $product_2 = new WC_Product_Simple; + $product_2->set_regular_price( '14' ); + $product_2->set_sale_price( '12.5' ); + $product_2->set_price( '12.5' ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'regular_price' => 12.5 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'sale_price' => 12.5 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'price' => 12.5 ) ); + $this->assertEquals( array( $product_1->get_id(), $product_2->get_id() ), $products ); + } + + /** + * Tests wc_get_products() with total_sales parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_total_sales() { + $product_1 = new WC_Product_Simple; + $product_1->set_total_sales( 4 ); + $product_1->save(); + + $product_2 = new WC_Product_Simple; + $product_2->set_total_sales( 2 ); + $product_2->save(); + + $product_3 = new WC_Product_Simple; + $product_3->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'total_sales' => 4 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + } + + /** + * Tests wc_get_products() with boolean parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_booleans() { + $product_1 = new WC_Product_Simple; + $product_1->set_virtual( true ); + $product_1->set_downloadable( true ); + $product_1->set_featured( true ); + $product_1->set_sold_individually( true ); + $product_1->set_backorders( 'no' ); + $product_1->set_manage_stock( false ); + $product_1->set_reviews_allowed( true ); + $product_1->save(); + + $product_2 = new WC_Product_Simple; + $product_2->set_virtual( false ); + $product_2->set_downloadable( false ); + $product_2->set_featured( false ); + $product_2->set_sold_individually( false ); + $product_2->set_backorders( 'notify' ); + $product_2->set_manage_stock( true ); + $product_2->set_reviews_allowed( false ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'virtual' => true ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'virtual' => false ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'downloadable' => false ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + // TODO: Fix featured query. + //$products = wc_get_products( array( 'return' => 'ids', 'featured' => true ) ); + //$this->assertEquals( array( $product_1->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'sold_individually' => true ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'backorders' => 'notify' ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'manage_stock' => true ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + // TODO: Fix this to use comment status in query args + //$products = wc_get_products( array( 'return' => 'ids', 'reviews_allowed' => true ) ); + //$this->assertEquals( array( $product_1->get_id() ), $products ); + } + + /** + * Tests wc_get_products() with visibility parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_visibility() { + + } + + /** + * Tests wc_get_products() with stock parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_stock() { + + } + + /** + * Tests wc_get_products() with tax parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_tax() { + + } + + /** + * Tests wc_get_products() with shipping parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_shipping_class() { + + } + + /** + * Tests wc_get_products() with download parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_download() { + + } + + /** + * Tests wc_get_products() with reviews parameters. + * + * @since 3.2.0 + */ + public function test_wc_get_products_reviews() { + + } + /** * Test wc_get_product(). * From 7781b2ea4db8c37e7092fb61a09974e2fbe3619b Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Tue, 25 Jul 2017 11:54:03 +0800 Subject: [PATCH 072/127] [#16242] Add context to woocommerce_backordered_item_meta_name --- includes/class-wc-order-item-product.php | 2 +- includes/legacy/abstract-wc-legacy-order.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index 2cf90dfb801..0e15e277c46 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -198,7 +198,7 @@ class WC_Order_Item_Product extends WC_Order_Item { public function set_backorder_meta() { $product = $this->get_product(); if ( $product && $product->backorders_require_notification() && $product->is_on_backorder( $this->get_quantity() ) ) { - $this->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $this->get_quantity() - max( 0, $product->get_stock_quantity() ), true ); + $this->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ), $this ), $this->get_quantity() - max( 0, $product->get_stock_quantity() ), true ); } } diff --git a/includes/legacy/abstract-wc-legacy-order.php b/includes/legacy/abstract-wc-legacy-order.php index 976013e120e..30faea7c8af 100644 --- a/includes/legacy/abstract-wc-legacy-order.php +++ b/includes/legacy/abstract-wc-legacy-order.php @@ -161,7 +161,7 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { // Handle qty if set. if ( isset( $args['qty'] ) ) { if ( $product->backorders_require_notification() && $product->is_on_backorder( $args['qty'] ) ) { - $item->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $args['qty'] - max( 0, $product->get_stock_quantity() ), true ); + $item->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ), $item ), $args['qty'] - max( 0, $product->get_stock_quantity() ), true ); } $args['subtotal'] = $args['subtotal'] ? $args['subtotal'] : wc_get_price_excluding_tax( $product, array( 'qty' => $args['qty'] ) ); $args['total'] = $args['total'] ? $args['total'] : wc_get_price_excluding_tax( $product, array( 'qty' => $args['qty'] ) ); From 689c5e7006d22e0acabdb1225302067e21d0b9d2 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Tue, 25 Jul 2017 08:36:01 -0700 Subject: [PATCH 073/127] Better code --- .../class-wc-product-data-store-cpt.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 359ccca713d..1b5e34d798b 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1295,7 +1295,6 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da } } - // SKU needs special handling because it works with partial matches. // Don't auto-generate meta query args for it. $sku_query = false; @@ -1304,14 +1303,6 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da unset( $query_vars['sku'] ); } - // total_sales needs special handline because the meta key doesn't have the underscore prefix. - // Don't auto generate meta query args for it. - $total_sales_query = false; - if ( isset( $query_vars['total_sales'] ) ) { - $total_sales_query = $query_vars['total_sales']; - unset( $query_vars['total_sales'] ); - } - $wp_query_args = parent::get_wp_query_args( $query_vars ); if ( ! isset( $wp_query_args['date_query'] ) ) { @@ -1331,10 +1322,11 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da } // Manually build the total_sales query if needed. - if ( $total_sales_query ) { + // This query doesn't get auto-generated since the meta key doesn't have the underscore prefix. + if ( isset( $query_vars['total_sales'] ) && '' !== $query_vars['total_sales'] ) { $wp_query_args['meta_query'][] = array( 'key' => 'total_sales', - 'value' => $total_sales_query, + 'value' => absint( $query_vars['total_sales'] ), 'compare' => '=', ); } From ec6d11bd67cfff42c02895e4ddcfe0b205b2c355 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Tue, 25 Jul 2017 10:01:24 -0700 Subject: [PATCH 074/127] Just needs visibility support and cleanup --- .../class-wc-product-data-store-cpt.php | 99 ++++++++++++----- tests/unit-tests/product/functions.php | 100 ++++++++++++++++-- 2 files changed, 169 insertions(+), 30 deletions(-) diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 1b5e34d798b..44c1d072997 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -45,6 +45,8 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da '_product_attributes', '_virtual', '_downloadable', + '_download_limit', + '_download_expiry', '_featured', '_downloadable_files', '_wc_rating_count', @@ -1257,6 +1259,19 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da } } + public function reviews_allowed_query_where( $where, $wp_query ) { + global $wpdb; + + if ( isset( $wp_query->query_vars['reviews_allowed'] ) && is_bool( $wp_query->query_vars['reviews_allowed'] ) ) { + if ( $wp_query->query_vars['reviews_allowed'] ) { + $where .= " AND $wpdb->posts.comment_status = 'open'"; + } else { + $where .= " AND $wpdb->posts.comment_status = 'closed'"; + } + } + + return $where; + } /** * Get valid WP_Query args from a WC_Product_Query's query variables. @@ -1269,9 +1284,12 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da // Map query vars to ones that get_wp_query_args or WP_Query recognize. $key_mapping = array( - 'status' => 'post_status', - 'page' => 'paged', - 'include' => 'post__in', + 'status' => 'post_status', + 'page' => 'paged', + 'include' => 'post__in', + 'stock_quantity' => 'stock', + 'average_rating' => 'wc_average_rating', + 'review_count' => 'wc_review_count', ); foreach ( $key_mapping as $query_key => $db_key ) { if ( isset( $query_vars[ $query_key ] ) ) { @@ -1284,10 +1302,8 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da $boolean_queries = array( 'virtual', 'downloadable', - 'featured', 'sold_individually', 'manage_stock', - 'reviews_allowed', ); foreach ( $boolean_queries as $boolean_query ) { if ( isset( $query_vars[ $boolean_query ] ) && is_bool( $query_vars[ $boolean_query ] ) ) { @@ -1303,6 +1319,13 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da unset( $query_vars['sku'] ); } + // Featured needs special handling because it's stored in terms not meta. + $featured_query = ''; + if ( isset( $query_vars['featured'] ) ) { + $featured_query = $query_vars['featured']; + unset( $query_vars['featured'] ); + } + $wp_query_args = parent::get_wp_query_args( $query_vars ); if ( ! isset( $wp_query_args['date_query'] ) ) { @@ -1312,25 +1335,6 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da $wp_query_args['meta_query'] = array(); } - // Add the special SKU query if needed. - if ( $sku_query ) { - $wp_query_args['meta_query'][] = array( - 'key' => '_sku', - 'value' => $sku_query, - 'compare' => 'LIKE', - ); - } - - // Manually build the total_sales query if needed. - // This query doesn't get auto-generated since the meta key doesn't have the underscore prefix. - if ( isset( $query_vars['total_sales'] ) && '' !== $query_vars['total_sales'] ) { - $wp_query_args['meta_query'][] = array( - 'key' => 'total_sales', - 'value' => absint( $query_vars['total_sales'] ), - 'compare' => '=', - ); - } - // Handle product types. if ( 'variation' === $query_vars['type'] ) { $wp_query_args['post_type'] = 'product_variation'; @@ -1375,6 +1379,25 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da ); } + // Add the special SKU query if needed. + if ( $sku_query ) { + $wp_query_args['meta_query'][] = array( + 'key' => '_sku', + 'value' => $sku_query, + 'compare' => 'LIKE', + ); + } + + // Manually build the total_sales query if needed. + // This query doesn't get auto-generated since the meta key doesn't have the underscore prefix. + if ( isset( $query_vars['total_sales'] ) && '' !== $query_vars['total_sales'] ) { + $wp_query_args['meta_query'][] = array( + 'key' => 'total_sales', + 'value' => absint( $query_vars['total_sales'] ), + 'compare' => '=', + ); + } + if ( ! empty( $query_vars['shipping_class'] ) ) { $wp_query_args['tax_query'][] = array( 'taxonomy' => 'product_shipping_class', @@ -1383,6 +1406,30 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da ); } + if ( '' !== $featured_query ) { + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + if ( $featured_query ) { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['featured'] ), + ); + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['exclude-from-catalog'] ), + 'operator' => 'NOT IN', + ); + } else { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['featured'] ), + 'operator' => 'NOT IN', + ); + } + } + $date_queries = array( 'date_created' => 'post_date', 'date_modified' => 'post_modified', @@ -1406,6 +1453,10 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da $wp_query_args['no_found_rows'] = true; } + if ( isset( $query_vars['reviews_allowed'] ) && is_bool( $query_vars['reviews_allowed'] ) ) { + add_filter( 'posts_where', array( $this, 'reviews_allowed_query_where' ), 10, 2 ); + } + return apply_filters( 'woocommerce_product_data_store_cpt_get_products_query', $wp_query_args, $query_vars, $this ); } diff --git a/tests/unit-tests/product/functions.php b/tests/unit-tests/product/functions.php index 9980f7c8dea..c9149921037 100644 --- a/tests/unit-tests/product/functions.php +++ b/tests/unit-tests/product/functions.php @@ -237,9 +237,10 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { $products = wc_get_products( array( 'return' => 'ids', 'downloadable' => false ) ); $this->assertEquals( array( $product_2->get_id() ), $products ); - // TODO: Fix featured query. - //$products = wc_get_products( array( 'return' => 'ids', 'featured' => true ) ); - //$this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'featured' => true ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'featured' => false ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); $products = wc_get_products( array( 'return' => 'ids', 'sold_individually' => true ) ); $this->assertEquals( array( $product_1->get_id() ), $products ); @@ -250,9 +251,10 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { $products = wc_get_products( array( 'return' => 'ids', 'manage_stock' => true ) ); $this->assertEquals( array( $product_2->get_id() ), $products ); - // TODO: Fix this to use comment status in query args - //$products = wc_get_products( array( 'return' => 'ids', 'reviews_allowed' => true ) ); - //$this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'reviews_allowed' => true ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'reviews_allowed' => false ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); } /** @@ -270,7 +272,25 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { * @since 3.2.0 */ public function test_wc_get_products_stock() { + $product_1 = new WC_Product_Simple; + $product_1->set_manage_stock( true ); + $product_1->set_stock_status( 'instock' ); + $product_1->set_stock_quantity( 5 ); + $product_1->save(); + $product_2 = new WC_Product_Simple; + $product_2->set_manage_stock( true ); + $product_2->set_stock_status( 'outofstock' ); + $product_2->set_stock_quantity( 0 ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'stock_quantity' => 5 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'stock_quantity' => 0 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'stock_status' => 'outofstock' ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); } /** @@ -279,7 +299,23 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { * @since 3.2.0 */ public function test_wc_get_products_tax() { + $product_1 = new WC_Product_Simple; + $product_1->set_tax_status( 'taxable' ); + $product_1->set_tax_class( 'reduced-rate' ); + $product_1->save(); + $product_2 = new WC_Product_Simple; + $product_2->set_tax_status( 'none' ); + $product_2->set_tax_class( 'standard' ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'tax_status' => 'taxable' ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'tax_status' => 'none' ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'tax_class' => 'reduced-rate' ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); } /** @@ -288,7 +324,21 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { * @since 3.2.0 */ public function test_wc_get_products_shipping_class() { + $shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' ); + $shipping_class_2 = wp_insert_term( 'Standard', 'product_shipping_class' ); + $product_1 = new WC_Product_Simple; + $product_1->set_shipping_class_id( $shipping_class_1['term_id'] ); + $product_1->save(); + + $product_2 = new WC_Product_Simple; + $product_2->set_shipping_class_id( $shipping_class_2['term_id'] ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'shipping_class' => 'bulky' ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'shipping_class' => 'standard' ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); } /** @@ -297,7 +347,27 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { * @since 3.2.0 */ public function test_wc_get_products_download() { + $product_1 = new WC_Product_Simple; + $product_1->set_downloadable( true ); + $product_1->set_download_limit( 5 ); + $product_1->set_download_expiry( 90 ); + $product_1->save(); + $product_2 = new WC_Product_Simple; + $product_2->set_downloadable( true ); + $product_2->set_download_limit( -1 ); + $product_2->set_download_expiry( -1 ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'download_limit' => 5 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'download_limit' => -1 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'download_expiry' => 90 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'download_expiry' => -1 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); } /** @@ -306,7 +376,25 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { * @since 3.2.0 */ public function test_wc_get_products_reviews() { + $product_1 = new WC_Product_Simple; + $product_1->set_average_rating( 5.0 ); + $product_1->set_review_count( 5 ); + $product_1->save(); + $product_2 = new WC_Product_Simple; + $product_2->set_average_rating( 3.0 ); + $product_2->set_review_count( 1 ); + $product_2->save(); + + $products = wc_get_products( array( 'return' => 'ids', 'average_rating' => 5.0 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'average_rating' => 3.0 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); + + $products = wc_get_products( array( 'return' => 'ids', 'review_count' => 5 ) ); + $this->assertEquals( array( $product_1->get_id() ), $products ); + $products = wc_get_products( array( 'return' => 'ids', 'review_count' => 1 ) ); + $this->assertEquals( array( $product_2->get_id() ), $products ); } /** From fe0c190894aa3943f72c15a46e73c5858ced29f7 Mon Sep 17 00:00:00 2001 From: Kathy Darling Date: Tue, 25 Jul 2017 14:43:26 -0400 Subject: [PATCH 075/127] Move settings init/save to load-$settings hook. Closes #16221 --- includes/admin/class-wc-admin-menus.php | 23 ++++++++++++++++++++++ includes/admin/class-wc-admin-settings.php | 21 -------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/includes/admin/class-wc-admin-menus.php b/includes/admin/class-wc-admin-menus.php index 09aee416b64..1513a6c261b 100644 --- a/includes/admin/class-wc-admin-menus.php +++ b/includes/admin/class-wc-admin-menus.php @@ -86,8 +86,31 @@ class WC_Admin_Menus { * Loads gateways and shipping methods into memory for use within settings. */ public function settings_page_init() { + global $current_tab, $current_section; + WC()->payment_gateways(); WC()->shipping(); + + // Include settings pages + WC_Admin_Settings::get_settings_pages(); + + // Get current tab/section + $current_tab = empty( $_GET['tab'] ) ? 'general' : sanitize_title( $_GET['tab'] ); + $current_section = empty( $_REQUEST['section'] ) ? '' : sanitize_title( $_REQUEST['section'] ); + + // Save settings if data has been posted + if ( ! empty( $_POST ) ) { + WC_Admin_Settings::save(); + } + + // Add any posted messages + if ( ! empty( $_GET['wc_error'] ) ) { + WC_Admin_Settings::add_error( stripslashes( $_GET['wc_error'] ) ); + } + + if ( ! empty( $_GET['wc_message'] ) ) { + WC_Admin_Settings::add_message( stripslashes( $_GET['wc_message'] ) ); + } } /** diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index e8fb57e0204..1828bcaac03 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -141,27 +141,6 @@ class WC_Admin_Settings { 'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'woocommerce' ), ) ); - // Include settings pages - self::get_settings_pages(); - - // Get current tab/section - $current_tab = empty( $_GET['tab'] ) ? 'general' : sanitize_title( $_GET['tab'] ); - $current_section = empty( $_REQUEST['section'] ) ? '' : sanitize_title( $_REQUEST['section'] ); - - // Save settings if data has been posted - if ( ! empty( $_POST ) ) { - self::save(); - } - - // Add any posted messages - if ( ! empty( $_GET['wc_error'] ) ) { - self::add_error( stripslashes( $_GET['wc_error'] ) ); - } - - if ( ! empty( $_GET['wc_message'] ) ) { - self::add_message( stripslashes( $_GET['wc_message'] ) ); - } - // Get tabs for the settings page $tabs = apply_filters( 'woocommerce_settings_tabs_array', array() ); From 15c4910014669b0e6242c3bb612d619b3c2342f9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 25 Jul 2017 21:03:37 +0100 Subject: [PATCH 076/127] Fix notices --- templates/order/form-tracking.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/order/form-tracking.php b/templates/order/form-tracking.php index 72c6e3b28fe..4851367f107 100644 --- a/templates/order/form-tracking.php +++ b/templates/order/form-tracking.php @@ -13,7 +13,7 @@ * @see https://docs.woocommerce.com/document/template-structure/ * @author WooThemes * @package WooCommerce/Templates - * @version 1.6.4 + * @version 3.2.0 */ if ( ! defined( 'ABSPATH' ) ) { @@ -28,8 +28,8 @@ global $post;

    -

    -

    +

    +

    From e44120581168dc00d022c285e68288d47b230d6a Mon Sep 17 00:00:00 2001 From: Daniel Rey Lopez Date: Wed, 26 Jul 2017 11:01:17 +0100 Subject: [PATCH 077/127] Fixes incorrect "name" property of the State + ' + '' @@ -3940,7 +3939,7 @@ S2.define('select2/dropdown/search',[ '' + '' + + ' spellcheck="false" role="combobox" aria-autocomplete="list" aria-expanded="true" />' + '' ); diff --git a/assets/js/selectWoo/selectWoo.full.min.js b/assets/js/selectWoo/selectWoo.full.min.js index 5e509a2bcc0..46b146cdca9 100644 --- a/assets/js/selectWoo/selectWoo.full.min.js +++ b/assets/js/selectWoo/selectWoo.full.min.js @@ -1 +1 @@ -/*! Select2 5.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
      ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(''),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()});b.$results.find(".select2-results__option[data-selected]").each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("data-selected","true"):b.attr("data-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"option","data-selected":"false"};b.disabled&&(delete d["data-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["data-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d["aria-label"]=b.text,delete d["data-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("data-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[data-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[data-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted").attr("aria-selected","true"),d.$results.attr("aria-activedescendant",a.element.attr("id"))}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[data-selected]",function(b){var c=a(this),e=c.data("data");if("true"===c.attr("data-selected"))return void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{}));d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[data-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted").attr("aria-selected","false"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[data-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results"),f=this.options.get("minimumResultsForSearch")===1/0;this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){f&&d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),f&&d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),window.setTimeout(function(){d.$selection.focus()},1),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("keydown",function(b){!a.isOpen()&&b.which>=48&&b.which<=90&&a.open()}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
        '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('
      • ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this,f=b.id+"-results";a.call(this,b,d),b.on("open",function(){e.$search.attr("aria-owns",f),e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d="";return d+=null!=b?b.id:a.generateChars(4),d+="-result-",d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this,f=c.id+"-results";b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.attr("aria-owns",f),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}}),c.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
      • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(f=d(this))&&g.push(f)})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;if(this._isInitialized)return void b.call(this,c);this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this,f=b.id+"-results";a.call(this,b,d),b.on("open",function(){e.$search.attr("aria-owns",f),e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d="";return d+=null!=b?b.id:a.generateChars(4),d+="-result-",d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this,f=c.id+"-results";b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.attr("aria-owns",f),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}}),c.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
      • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(f=d(this))&&g.push(f)})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;if(this._isInitialized)return void b.call(this,c);this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `' + '' @@ -3940,7 +3939,7 @@ S2.define('select2/dropdown/search',[ '' + '' + + ' spellcheck="false" role="combobox" aria-autocomplete="list" aria-expanded="true" />' + '' ); diff --git a/assets/js/selectWoo/selectWoo.min.js b/assets/js/selectWoo/selectWoo.min.js index 456ebbfdcaa..ecbf4173908 100644 --- a/assets/js/selectWoo/selectWoo.min.js +++ b/assets/js/selectWoo/selectWoo.min.js @@ -1 +1 @@ -/*! Select2 5.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
          ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(''),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()});b.$results.find(".select2-results__option[data-selected]").each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("data-selected","true"):b.attr("data-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"option","data-selected":"false"};b.disabled&&(delete d["data-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["data-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d["aria-label"]=b.text,delete d["data-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("data-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[data-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[data-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted").attr("aria-selected","true"),d.$results.attr("aria-activedescendant",a.element.attr("id"))}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[data-selected]",function(b){var c=a(this),e=c.data("data");if("true"===c.attr("data-selected"))return void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{}));d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[data-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted").attr("aria-selected","false"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[data-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results"),f=this.options.get("minimumResultsForSearch")===1/0;this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){f&&d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),f&&d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),window.setTimeout(function(){d.$selection.focus()},1),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("keydown",function(b){!a.isOpen()&&b.which>=48&&b.which<=90&&a.open()}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
            '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('
          • ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this,f=b.id+"-results";a.call(this,b,d),b.on("open",function(){e.$search.attr("aria-owns",f),e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d="";return d+=null!=b?b.id:a.generateChars(4),d+="-result-",d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this,f=c.id+"-results";b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.attr("aria-owns",f),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}}),c.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
          • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.selectWoo){var e=["open","close","destroy"];a.fn.selectWoo=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null!=a.fn.select2&&null!=a.fn.select2.defaults&&(a.fn.selectWoo.defaults=a.fn.select2.defaults),null==a.fn.selectWoo.defaults&&(a.fn.selectWoo.defaults=d),a.fn.select2=a.fn.select2||a.fn.selectWoo,c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,a.fn.selectWoo.amd=b,c}); \ No newline at end of file +/*! Select2 5.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
              ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(''),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()});b.$results.find(".select2-results__option[data-selected]").each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("data-selected","true"):b.attr("data-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"option","data-selected":"false"};b.disabled&&(delete d["data-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["data-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d["aria-label"]=b.text,delete d["data-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("data-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[data-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[data-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted").attr("aria-selected","true"),d.$results.attr("aria-activedescendant",a.element.attr("id"))}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[data-selected]",function(b){var c=a(this),e=c.data("data");if("true"===c.attr("data-selected"))return void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{}));d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[data-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted").attr("aria-selected","false"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[data-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.options.get("minimumResultsForSearch");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),window.setTimeout(function(){d.$selection.focus()},1),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",d),this.$selection.attr("role","combobox"),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("keydown",function(b){!a.isOpen()&&b.which>=48&&b.which<=90&&a.open()}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
                '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('
              • ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this,f=b.id+"-results";a.call(this,b,d),b.on("open",function(){e.$search.attr("aria-owns",f),e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d="";return d+=null!=b?b.id:a.generateChars(4),d+="-result-",d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this,f=c.id+"-results";b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.attr("aria-owns",f),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.removeAttr("aria-activedescendant"),e.$search.removeAttr("aria-owns"),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}}),c.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.data._resultId)})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
              • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.selectWoo){var e=["open","close","destroy"];a.fn.selectWoo=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null!=a.fn.select2&&null!=a.fn.select2.defaults&&(a.fn.selectWoo.defaults=a.fn.select2.defaults),null==a.fn.selectWoo.defaults&&(a.fn.selectWoo.defaults=d),a.fn.select2=a.fn.select2||a.fn.selectWoo,c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,a.fn.selectWoo.amd=b,c}); \ No newline at end of file From 48f03b15ed0a8462b3ad4a4576ef7dec8ea53be4 Mon Sep 17 00:00:00 2001 From: claudiulodro Date: Fri, 4 Aug 2017 14:27:22 -0700 Subject: [PATCH 101/127] Use correct server variable --- includes/class-wc-geolocation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-geolocation.php b/includes/class-wc-geolocation.php index 3ee4fa27cbe..66617a3bf99 100644 --- a/includes/class-wc-geolocation.php +++ b/includes/class-wc-geolocation.php @@ -98,8 +98,8 @@ class WC_Geolocation { * @return string */ public static function get_ip_address() { - if ( isset( $_SERVER['X-Real-IP'] ) ) { - return $_SERVER['X-Real-IP']; + if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { + return $_SERVER['HTTP_X_REAL_IP']; } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { // Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2 // Make sure we always only send through the first IP in the list which should always be the client IP. From 8ebe8a1720c44d28b226a41b9d0d950b506cd9a9 Mon Sep 17 00:00:00 2001 From: James Kemp Date: Sat, 5 Aug 2017 12:05:47 +0100 Subject: [PATCH 102/127] Add sorting ID and menu orders to sorting action --- includes/class-wc-ajax.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index 1e41cb4a022..93489455a89 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -1411,7 +1411,7 @@ class WC_AJAX { $wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_orders[ $sorting_id ] ), array( 'ID' => $sorting_id ) ); - do_action( 'woocommerce_after_product_ordering' ); + do_action( 'woocommerce_after_product_ordering', $sorting_id, $menu_orders ); wp_send_json( $menu_orders ); } From 393abc96193c6a973576f206c2e9c71229853191 Mon Sep 17 00:00:00 2001 From: Jesse Ostrander Date: Sun, 6 Aug 2017 12:16:46 -0400 Subject: [PATCH 103/127] Fix typo in login-form.php template. Woocomerce -> woocommerce --- templates/myaccount/form-login.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/myaccount/form-login.php b/templates/myaccount/form-login.php index c916fdd48f1..426afb8f757 100644 --- a/templates/myaccount/form-login.php +++ b/templates/myaccount/form-login.php @@ -36,7 +36,7 @@ if ( ! defined( 'ABSPATH' ) ) {

                -
                - -

                From d46988b6a6d397f69ebeee6e45b6376b01b53b79 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 7 Aug 2017 12:39:16 +0100 Subject: [PATCH 111/127] Improve add payment method logic --- includes/class-wc-form-handler.php | 36 ++++++++++++++++++-------- includes/class-wc-payment-gateways.php | 4 +-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index 25c7f750764..a4be37cdc3c 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -374,27 +374,41 @@ class WC_Form_Handler { */ public static function add_payment_method_action() { if ( isset( $_POST['woocommerce_add_payment_method'], $_POST['payment_method'], $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-add-payment-method' ) ) { - ob_start(); - $payment_method = wc_clean( $_POST['payment_method'] ); - + $payment_method_id = wc_clean( wp_unslash( $_POST['payment_method'] ) ); $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); - // Validate - $available_gateways[ $payment_method ]->validate_fields(); - // Process - if ( wc_notice_count( 'wc_errors' ) == 0 ) { - $result = $available_gateways[ $payment_method ]->add_payment_method(); - // Redirect to success/confirmation/payment page + if ( isset( $available_gateways[ $payment_method_id ] ) ) { + $gateway = $available_gateways[ $payment_method_id ]; + + if ( ! $gateway->supports( 'add_payment_method' ) && ! $gateway->supports( 'tokenization' ) ) { + wc_add_notice( __( 'Invalid payment gateway.', 'woocommerce' ), 'error' ); + return; + } + + $gateway->validate_fields(); + + if ( wc_notice_count( 'error' ) > 0 ) { + return; + } + + $result = $gateway->add_payment_method(); + if ( 'success' === $result['result'] ) { - wc_add_notice( __( 'Payment method added.', 'woocommerce' ) ); + wc_add_notice( __( 'Payment method successfully added.', 'woocommerce' ) ); + } + + if ( 'failure' === $result['result'] ) { + wc_add_notice( __( 'Unable to add payment method to your account.', 'woocommerce' ), 'error' ); + } + + if ( ! empty( $result['redirect'] ) ) { wp_redirect( $result['redirect'] ); exit(); } } } - } /** diff --git a/includes/class-wc-payment-gateways.php b/includes/class-wc-payment-gateways.php index 46fc76063a7..b04e72ad318 100644 --- a/includes/class-wc-payment-gateways.php +++ b/includes/class-wc-payment-gateways.php @@ -154,9 +154,7 @@ class WC_Payment_Gateways { if ( $gateway->is_available() ) { if ( ! is_add_payment_method_page() ) { $_available_gateways[ $gateway->id ] = $gateway; - } elseif ( $gateway->supports( 'add_payment_method' ) ) { - $_available_gateways[ $gateway->id ] = $gateway; - } elseif ( $gateway->supports( 'tokenization' ) ) { + } elseif ( $gateway->supports( 'add_payment_method' ) || $gateway->supports( 'tokenization' ) ) { $_available_gateways[ $gateway->id ] = $gateway; } } From 9022261f13f558ceba5f9c7292a3d82248bfa9f0 Mon Sep 17 00:00:00 2001 From: Boro Sitnikovski Date: Mon, 7 Aug 2017 15:29:17 +0200 Subject: [PATCH 112/127] Fix cache issue. From discussion with @mikejolley: The class is not doing its job of invaliding cache after adding a line item. At any point (action hook), a 3pd can call `get_items` and it will cache the items for that particular order so any subsequent calls to it will return bad data. Unless you ADD items, `get_items` will return good data. So adding items in this case is not invalidating, so that's the bug. Relates to: https://github.com/woocommerce/woocommerce-bookings/issues/1310 --- includes/data-stores/abstract-wc-order-item-type-data-store.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/data-stores/abstract-wc-order-item-type-data-store.php b/includes/data-stores/abstract-wc-order-item-type-data-store.php index 3de53d7c547..9bbf98f4a6c 100644 --- a/includes/data-stores/abstract-wc-order-item-type-data-store.php +++ b/includes/data-stores/abstract-wc-order-item-type-data-store.php @@ -143,5 +143,6 @@ abstract class Abstract_WC_Order_Item_Type_Data_Store extends WC_Data_Store_WP i */ public function clear_cache( &$item ) { wp_cache_delete( 'item-' . $item->get_id(), 'order-items' ); + wp_cache_delete( 'order-items-' . $item->get_order_id(), 'orders' ); } } From 8db31eefe2a27f73cc696c18bce5cc72500a0869 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 7 Aug 2017 15:16:38 +0100 Subject: [PATCH 113/127] Fix variable stock status setting by using CRUD methods Closes #16287 --- includes/admin/class-wc-admin-post-types.php | 115 ++++++++----------- 1 file changed, 50 insertions(+), 65 deletions(-) diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index 4b1aa4cee3c..20d3f25498c 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -1032,40 +1032,33 @@ class WC_Admin_Post_Types { $stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : 'instock'; $stock_amount = 'yes' === $manage_stock ? wc_stock_amount( $_REQUEST['_stock'] ) : ''; + $product->set_manage_stock( $manage_stock ); + $product->set_backorders( $backorders ); + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { - - // Apply product type constraints to stock status - if ( $product->is_type( 'external' ) ) { - // External always in stock - $stock_status = 'instock'; - } elseif ( $product->is_type( 'variable' ) ) { - // Stock status is always determined by children - foreach ( $product->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! $product->get_manage_stock() ) { - $child->set_stock_status( $stock_status ); - $child->save(); - } - } - - $product = WC_Product_Variable::sync( $product, false ); - } - - $product->set_manage_stock( $manage_stock ); - $product->set_backorders( $backorders ); - $product->save(); - - if ( ! $product->is_type( 'variable' ) ) { - wc_update_product_stock_status( $post_id, $stock_status ); - } - - wc_update_product_stock( $post_id, $stock_amount ); - - } else { - $product->save(); - wc_update_product_stock_status( $post_id, $stock_status ); + $product->set_stock_quantity( $stock_amount ); } + // Apply product type constraints to stock status. + if ( $product->is_type( 'external' ) ) { + // External products are always in stock. + $product->set_stock_status( 'instock' ); + } elseif ( $product->is_type( 'variable' ) && ! $product->get_manage_stock() ) { + // Stock status is determined by children. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! $product->get_manage_stock() ) { + $child->set_stock_status( $stock_status ); + $child->save(); + } + } + $product = WC_Product_Variable::sync( $product, false ); + } else { + $product->set_stock_status( $stock_status ); + } + + $product->save(); + do_action( 'woocommerce_product_quick_edit_save', $product ); } @@ -1243,9 +1236,8 @@ class WC_Admin_Post_Types { $was_managing_stock = $product->get_manage_stock() ? 'yes' : 'no'; $stock_status = $product->get_stock_status(); $backorders = $product->get_backorders(); - - $backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : $backorders; - $stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : $stock_status; + $backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : $backorders; + $stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : $stock_status; if ( ! empty( $_REQUEST['_manage_stock'] ) ) { $manage_stock = 'yes' === wc_clean( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no'; @@ -1255,40 +1247,33 @@ class WC_Admin_Post_Types { $stock_amount = 'yes' === $manage_stock && ! empty( $_REQUEST['change_stock'] ) ? wc_stock_amount( $_REQUEST['_stock'] ) : $product->get_stock_quantity(); + $product->set_manage_stock( $manage_stock ); + $product->set_backorders( $backorders ); + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { - - // Apply product type constraints to stock status - if ( $product->is_type( 'external' ) ) { - // External always in stock - $stock_status = 'instock'; - } elseif ( $product->is_type( 'variable' ) ) { - // Stock status is always determined by children - foreach ( $product->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! $product->get_manage_stock() ) { - $child->set_stock_status( $stock_status ); - $child->save(); - } - } - - $product = WC_Product_Variable::sync( $product, false ); - } - - $product->set_manage_stock( $manage_stock ); - $product->set_backorders( $backorders ); - $product->save(); - - if ( ! $product->is_type( 'variable' ) ) { - wc_update_product_stock_status( $post_id, $stock_status ); - } - - wc_update_product_stock( $post_id, $stock_amount ); - - } else { - $product->save(); - wc_update_product_stock_status( $post_id, $stock_status ); + $product->set_stock_quantity( $stock_amount ); } + // Apply product type constraints to stock status. + if ( $product->is_type( 'external' ) ) { + // External products are always in stock. + $product->set_stock_status( 'instock' ); + } elseif ( $product->is_type( 'variable' ) && ! $product->get_manage_stock() ) { + // Stock status is determined by children. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! $product->get_manage_stock() ) { + $child->set_stock_status( $stock_status ); + $child->save(); + } + } + $product = WC_Product_Variable::sync( $product, false ); + } else { + $product->set_stock_status( $stock_status ); + } + + $product->save(); + do_action( 'woocommerce_product_bulk_edit_save', $product ); } From 622b4b35d6d212d25aafe09bbf23f753f1137b89 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 7 Aug 2017 17:10:36 +0100 Subject: [PATCH 114/127] Remove white space --- includes/class-wc-cache-helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-cache-helper.php b/includes/class-wc-cache-helper.php index 7bbef730277..fb72f26b035 100644 --- a/includes/class-wc-cache-helper.php +++ b/includes/class-wc-cache-helper.php @@ -156,7 +156,7 @@ class WC_Cache_Helper { return; } $page_ids = array_filter( array( wc_get_page_id( 'cart' ), wc_get_page_id( 'checkout' ), wc_get_page_id( 'myaccount' ) ) ); - + if ( isset( $_GET['download_file'] ) || is_page( $page_ids ) ) { self::nocache(); } From 5e2ce545307359722f1e2692384c8b8390c3c0ff Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 7 Aug 2017 17:19:19 +0100 Subject: [PATCH 115/127] update tests --- tests/unit-tests/product/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit-tests/product/functions.php b/tests/unit-tests/product/functions.php index d4b9be2ce97..2c9f824b508 100644 --- a/tests/unit-tests/product/functions.php +++ b/tests/unit-tests/product/functions.php @@ -631,7 +631,7 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { 'key' => '_price', 'value' => array( 10, 100 ), 'compare' => 'BETWEEN', - 'type' => 'NUMERIC', + 'type' => 'DECIMAL(10,2)', ), $meta_query ); } From 7a829036c2bb985ef8b7b88abb153e94802b3a7d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 7 Aug 2017 17:49:46 +0100 Subject: [PATCH 116/127] Fix tests --- includes/class-wc-tax.php | 2 +- tests/unit-tests/tax/tax.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-tax.php b/includes/class-wc-tax.php index e458dc68ee3..a772f093615 100644 --- a/includes/class-wc-tax.php +++ b/includes/class-wc-tax.php @@ -553,7 +553,7 @@ class WC_Tax { 'tax_class' => $tax_class, ) ); - } else { + } elseif ( WC()->cart->get_cart() ) { // This will be per order shipping - loop through the order and find the highest tax class rate $cart_tax_classes = WC()->cart->get_cart_item_tax_classes(); diff --git a/tests/unit-tests/tax/tax.php b/tests/unit-tests/tax/tax.php index f949570b87f..46474148703 100644 --- a/tests/unit-tests/tax/tax.php +++ b/tests/unit-tests/tax/tax.php @@ -63,7 +63,7 @@ class WC_Tests_Tax extends WC_Unit_Test_Case { $tax_rates = WC_Tax::get_shipping_tax_rates(); - $this->assertEquals( $tax_rates, array( $tax_rate_id => array( 'rate' => '20.0000', 'label' => 'VAT', 'shipping' => 'yes', 'compound' => 'no' ) ) ); + $this->assertEquals( $tax_rates, array( $tax_rate_id => array( 'rate' => '20.0000', 'label' => 'VAT', 'shipping' => 'yes', 'compound' => 'no' ) ), print_r( $tax_rates, true ) ); WC_Tax::_delete_tax_rate( $tax_rate_id ); } From dd36ae87d3118ca93d58524f5e9ba906b342453a Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 13 Jul 2017 19:55:47 -0300 Subject: [PATCH 117/127] Improved wc_create_attribute() inline doc --- includes/wc-attribute-functions.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index d44e6c98619..04d7f99b08c 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -382,17 +382,21 @@ function wc_get_attribute( $id ) { /** * Create attribute. * - * Options: - * - * id - Unique identifier, used to update an attribute. - * name - Attribute name. - * slug - Attribute alphanumeric identifier. - * type - Type of attribute, core options: 'select' and 'text', default to 'select'. - * order_by - Sort order, options: 'menu_order', 'name', 'name_num' and 'id'. - * has_archives - Enable or disable attribute archives. - * * @since 3.2.0 - * @param array $args Attribute arguments. + * @param array $args Attribute arguments { + * Array of attribute parameters. + * + * @type int $id Unique identifier, used to update an attribute. + * @type string $name Attribute name. Always required. + * @type string $slug Attribute alphanumeric identifier. + * @type string $type Type of attribute. + * Core by default accepts: 'select' and 'text'. + * Default to 'select'. + * @type string $order_by Sort order. + * Accepts: 'menu_order', 'name', 'name_num' and 'id'. + * Default to 'menu_order'. + * @type bool $has_archives Enable or disable attribute archives. False by default. + * } * @return int|WP_Error */ function wc_create_attribute( $args ) { From 29e73d27f4c754381f6221c9f77482e7cfcbffb7 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 13 Jul 2017 20:15:44 -0300 Subject: [PATCH 118/127] Introduced woocommerce_attribute_created And flush rewrite rules when created attribute. --- includes/wc-attribute-functions.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 04d7f99b08c..726cc5ca09e 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -472,7 +472,16 @@ function wc_create_attribute( $args ) { } } - // Clear transients. + /** + * Attribute created. + * + * @param int $id Created attribute ID. + * @param array $data Data used to created the attribute. + */ + do_action( 'woocommerce_attribute_created', $id, $data ); + + // Clear cache and flush rewrite rules. + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); delete_transient( 'wc_attribute_taxonomies' ); return $id; From 6dfcf95b5e83a15ce5a34d6669106c79a8c77aef Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 7 Aug 2017 21:40:24 -0300 Subject: [PATCH 119/127] Properly update and delete attributes - Now keep all the original hooks without deprecated anything, - Update product metadata and terms metadata while changing slugs. - Delete terms while deleting attributes --- includes/wc-attribute-functions.php | 125 +++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 23 deletions(-) diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 726cc5ca09e..9f3dd2ad1e2 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -408,7 +408,7 @@ function wc_create_attribute( $args ) { // Name is required. if ( empty( $args['name'] ) ) { - return new WP_Error( 'missing_attribute_name', __( 'Missing attribute name', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'missing_attribute_name', __( 'Please, provide an attribute name.', 'woocommerce' ), array( 'status' => 400 ) ); } // Set the attribute slug. @@ -423,7 +423,7 @@ function wc_create_attribute( $args ) { return new WP_Error( 'invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { return new WP_Error( 'invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); - } elseif ( 0 === $id && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + } elseif ( ( 0 === $id && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) || ( isset( $args['old_slug'] ) && $args['old_slug'] !== $args['slug'] && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) ) { return new WP_Error( 'invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } @@ -442,7 +442,7 @@ function wc_create_attribute( $args ) { 'attribute_name' => $slug, 'attribute_type' => $args['type'], 'attribute_orderby' => $args['order_by'], - 'attribute_public' => isset( $args['has_archives'] ) ? (bool) $args['has_archives'] : false, + 'attribute_public' => isset( $args['has_archives'] ) ? (int) $args['has_archives'] : 0, ); // Create or update. @@ -458,6 +458,14 @@ function wc_create_attribute( $args ) { } $id = $wpdb->insert_id; + + /** + * Attribute added. + * + * @param int $id Added attribute ID. + * @param array $data Attribute data. + */ + do_action( 'woocommerce_attribute_added', $id, $data ); } else { $results = $wpdb->update( $wpdb->prefix . 'woocommerce_attribute_taxonomies', @@ -470,15 +478,52 @@ function wc_create_attribute( $args ) { if ( false === $results ) { return new WP_Error( 'cannot_update_attribute', __( 'Could not update the attribute.', 'woocommerce' ), array( 'status' => 400 ) ); } - } - /** - * Attribute created. - * - * @param int $id Created attribute ID. - * @param array $data Data used to created the attribute. - */ - do_action( 'woocommerce_attribute_created', $id, $data ); + // Set old_slug to check for database chances. + $args['old_slug'] = ! empty( $args['old_slug'] ) ? $args['old_slug'] : $args['slug']; + + /** + * Attribute updated. + * + * @param int $id Added attribute ID. + * @param array $data Attribute data. + * @param string $old_slug Attribute old name. + */ + do_action( 'woocommerce_attribute_updated', $id, $data, $args['old_slug'] ); + + if ( $args['old_slug'] !== $args['slug'] ) { + // Update taxonomies in the wp term taxonomy table. + $wpdb->update( + $wpdb->term_taxonomy, + array( 'taxonomy' => wc_attribute_taxonomy_name( $data['attribute_name'] ) ), + array( 'taxonomy' => 'pa_' . $args['old_slug'] ) + ); + + // Update taxonomy ordering term meta. + $table_name = get_option( 'db_version' ) < 34370 ? $wpdb->prefix . 'woocommerce_termmeta' : $wpdb->termmeta; + $wpdb->update( + $table_name, + array( 'meta_key' => 'order_pa_' . sanitize_title( $data['attribute_name'] ) ), + array( 'meta_key' => 'order_pa_' . sanitize_title( $args['old_slug'] ) ) + ); + + // Update product attributes which use this taxonomy. + $old_attribute_name_length = strlen( $args['old_slug'] ) + 3; + $attribute_name_length = strlen( $data['attribute_name'] ) + 3; + + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE( meta_value, %s, %s ) WHERE meta_key = '_product_attributes'", + 's:' . $old_attribute_name_length . ':"pa_' . $args['old_slug'] . '"', + 's:' . $attribute_name_length . ':"pa_' . $data['attribute_name'] . '"' + ) ); + + // Update variations which use this taxonomy. + $wpdb->update( + $wpdb->postmeta, + array( 'meta_key' => 'attribute_pa_' . sanitize_title( $data['attribute_name'] ) ), + array( 'meta_key' => 'attribute_pa_' . sanitize_title( $args['old_slug'] ) ) + ); + } + } // Clear cache and flush rewrite rules. wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); @@ -495,9 +540,11 @@ function wc_create_attribute( $args ) { * @since 3.2.0 * @param int $id Attribute ID. * @param array $args Attribute arguments. - * @return int|WP_Error] + * @return int|WP_Error */ function wc_update_attribute( $id, $args ) { + global $wpdb; + $attribute = wc_get_attribute( $id ); $args['id'] = $attribute ? $attribute->id : 0; @@ -506,6 +553,13 @@ function wc_update_attribute( $id, $args ) { $args['name'] = $attribute->name; } + $args['old_slug'] = $wpdb->get_var( $wpdb->prepare( " + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $args['id'] + ) ); + return wc_create_attribute( $args ); } @@ -519,18 +573,43 @@ function wc_update_attribute( $id, $args ) { function wc_delete_attribute( $id ) { global $wpdb; - $deleted = $wpdb->delete( - $wpdb->prefix . 'woocommerce_attribute_taxonomies', - array( 'attribute_id' => $id ), - array( '%d' ) - ); + $name = $wpdb->get_var( $wpdb->prepare( " + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); - if ( in_array( $deleted, array( 0, false ), true ) ) { - return false; + $taxonomy = wc_attribute_taxonomy_name( $name ); + + /** + * Before delete an attribute. + * + * @param int $id Attribute ID. + * @param string $name Attribute name. + * @param string $taxonomy Attribute taxonomy name. + */ + do_action( 'woocommerce_before_attribute_delete', $id, $name, $taxonomy ); + + if ( $name && $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = $id" ) ) { + if ( taxonomy_exists( $taxonomy ) ) { + $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' ); + foreach ( $terms as $term ) { + wp_delete_term( $term->term_id, $taxonomy ); + } + } + + /** + * After delete an attribute. + * + * @param int $id Attribute ID. + * @param string $name Attribute name. + * @param string $taxonomy Attribute taxonomy name. + */ + do_action( 'woocommerce_attribute_deleted', $id, $name, $taxonomy ); + delete_transient( 'wc_attribute_taxonomies' ); + + return true; } - // Clear transients. - delete_transient( 'wc_attribute_taxonomies' ); - - return true; + return false; } From 27966150543fc3d290244e834b187d4e9ebc79f4 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 7 Aug 2017 22:23:50 -0300 Subject: [PATCH 120/127] Flush rewrite rules after delete attributes --- includes/wc-attribute-functions.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 9f3dd2ad1e2..984781414e5 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -606,6 +606,7 @@ function wc_delete_attribute( $id ) { * @param string $taxonomy Attribute taxonomy name. */ do_action( 'woocommerce_attribute_deleted', $id, $name, $taxonomy ); + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); delete_transient( 'wc_attribute_taxonomies' ); return true; From a3a3d7c24241b12c8b589adbf0d28f1a736f4305 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 7 Aug 2017 22:33:57 -0300 Subject: [PATCH 121/127] Initial implementation of product attribute helper functions --- includes/admin/class-wc-admin-attributes.php | 68 ++++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index d3c16cd0491..7323701b133 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -88,48 +88,38 @@ class WC_Admin_Attributes { return $attribute; } - /** - * See if an attribute name is valid. - * @param string $attribute_name - * @return bool|WP_error result - */ - private static function valid_attribute_name( $attribute_name ) { - if ( strlen( $attribute_name ) > 28 ) { - /* translators: %s: attribute name */ - return new WP_Error( 'error', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), sanitize_title( $attribute_name ) ) ); - } elseif ( wc_check_if_attribute_name_is_reserved( $attribute_name ) ) { - /* translators: %s: attribute name */ - return new WP_Error( 'error', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), sanitize_title( $attribute_name ) ) ); - } - - return true; - } - /** * Add an attribute. * @return bool|WP_Error */ private static function process_add_attribute() { - global $wpdb; check_admin_referer( 'woocommerce-add-new_attribute' ); $attribute = self::get_posted_attribute(); - if ( empty( $attribute['attribute_name'] ) || empty( $attribute['attribute_label'] ) ) { - return new WP_Error( 'error', __( 'Please, provide an attribute name and slug.', 'woocommerce' ) ); - } elseif ( ( $valid_attribute_name = self::valid_attribute_name( $attribute['attribute_name'] ) ) && is_wp_error( $valid_attribute_name ) ) { - return $valid_attribute_name; - } elseif ( taxonomy_exists( wc_attribute_taxonomy_name( $attribute['attribute_name'] ) ) ) { - /* translators: %s: attribute name */ - return new WP_Error( 'error', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), sanitize_title( $attribute['attribute_name'] ) ) ); + $args = array( + 'name' => $attribute['attribute_label'], + 'slug' => $attribute['attribute_name'], + 'type' => $attribute['attribute_type'], + 'order_by' => $attribute['attribute_orderby'], + 'has_archives' => $attribute['attribute_public'], + ); + + $id = wc_create_attribute( $args ); + + if ( is_wp_error( $id ) ) { + return $id; } - $wpdb->insert( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute ); - - do_action( 'woocommerce_attribute_added', $wpdb->insert_id, $attribute ); - - wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); - delete_transient( 'wc_attribute_taxonomies' ); + /** + * Attribute added. + * + * @deprecated 3.2.0 + * + * @param int $id Added attribute ID. + * @param array $attribute Attribute arguments. + */ + do_action( 'woocommerce_attribute_added', $id, $attribute ); return true; } @@ -145,10 +135,18 @@ class WC_Admin_Attributes { $attribute = self::get_posted_attribute(); - if ( empty( $attribute['attribute_name'] ) || empty( $attribute['attribute_label'] ) ) { - return new WP_Error( 'error', __( 'Please, provide an attribute name and slug.', 'woocommerce' ) ); - } elseif ( ( $valid_attribute_name = self::valid_attribute_name( $attribute['attribute_name'] ) ) && is_wp_error( $valid_attribute_name ) ) { - return $valid_attribute_name; + $args = array( + 'name' => $attribute['attribute_label'], + 'slug' => $attribute['attribute_name'], + 'type' => $attribute['attribute_type'], + 'order_by' => $attribute['attribute_orderby'], + 'has_archives' => $attribute['attribute_public'], + ); + + $id = wc_update_attribute( $attribute_id, $args ); + + if ( is_wp_error( $id ) ) { + return $id; } $taxonomy_exists = taxonomy_exists( wc_attribute_taxonomy_name( $attribute['attribute_name'] ) ); From 70e0ab857e6b973e1f5998d9e949ddfe3600dc79 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 7 Aug 2017 21:42:56 -0300 Subject: [PATCH 122/127] Implement attributes functions to admin --- includes/admin/class-wc-admin-attributes.php | 97 ++------------------ 1 file changed, 6 insertions(+), 91 deletions(-) diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index 7323701b133..3e46f1aaa57 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -90,14 +90,14 @@ class WC_Admin_Attributes { /** * Add an attribute. + * * @return bool|WP_Error */ private static function process_add_attribute() { check_admin_referer( 'woocommerce-add-new_attribute' ); $attribute = self::get_posted_attribute(); - - $args = array( + $args = array( 'name' => $attribute['attribute_label'], 'slug' => $attribute['attribute_name'], 'type' => $attribute['attribute_type'], @@ -111,31 +111,20 @@ class WC_Admin_Attributes { return $id; } - /** - * Attribute added. - * - * @deprecated 3.2.0 - * - * @param int $id Added attribute ID. - * @param array $attribute Attribute arguments. - */ - do_action( 'woocommerce_attribute_added', $id, $attribute ); - return true; } /** * Edit an attribute. + * * @return bool|WP_Error */ private static function process_edit_attribute() { - global $wpdb; $attribute_id = absint( $_GET['edit'] ); check_admin_referer( 'woocommerce-save-attribute_' . $attribute_id ); $attribute = self::get_posted_attribute(); - - $args = array( + $args = array( 'name' => $attribute['attribute_label'], 'slug' => $attribute['attribute_name'], 'type' => $attribute['attribute_type'], @@ -149,95 +138,21 @@ class WC_Admin_Attributes { return $id; } - $taxonomy_exists = taxonomy_exists( wc_attribute_taxonomy_name( $attribute['attribute_name'] ) ); - $old_attribute_name = $wpdb->get_var( "SELECT attribute_name FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = $attribute_id" ); - if ( $old_attribute_name != $attribute['attribute_name'] && wc_sanitize_taxonomy_name( $old_attribute_name ) != $attribute['attribute_name'] && $taxonomy_exists ) { - /* translators: %s: attribute name */ - return new WP_Error( 'error', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), sanitize_title( $attribute['attribute_name'] ) ) ); - } - - $wpdb->update( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute, array( 'attribute_id' => $attribute_id ) ); - - do_action( 'woocommerce_attribute_updated', $attribute_id, $attribute, $old_attribute_name ); - - if ( $old_attribute_name != $attribute['attribute_name'] && ! empty( $old_attribute_name ) ) { - // Update taxonomies in the wp term taxonomy table - $wpdb->update( - $wpdb->term_taxonomy, - array( 'taxonomy' => wc_attribute_taxonomy_name( $attribute['attribute_name'] ) ), - array( 'taxonomy' => 'pa_' . $old_attribute_name ) - ); - - // Update taxonomy ordering term meta - if ( get_option( 'db_version' ) < 34370 ) { - $wpdb->update( - $wpdb->prefix . 'woocommerce_termmeta', - array( 'meta_key' => 'order_pa_' . sanitize_title( $attribute['attribute_name'] ) ), - array( 'meta_key' => 'order_pa_' . sanitize_title( $old_attribute_name ) ) - ); - } else { - $wpdb->update( - $wpdb->termmeta, - array( 'meta_key' => 'order_pa_' . sanitize_title( $attribute['attribute_name'] ) ), - array( 'meta_key' => 'order_pa_' . sanitize_title( $old_attribute_name ) ) - ); - } - - // Update product attributes which use this taxonomy - $old_attribute_name_length = strlen( $old_attribute_name ) + 3; - $attribute_name_length = strlen( $attribute['attribute_name'] ) + 3; - - $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE( meta_value, %s, %s ) WHERE meta_key = '_product_attributes'", - 's:' . $old_attribute_name_length . ':"pa_' . $old_attribute_name . '"', - 's:' . $attribute_name_length . ':"pa_' . $attribute['attribute_name'] . '"' - ) ); - - // Update variations which use this taxonomy - $wpdb->update( - $wpdb->postmeta, - array( 'meta_key' => 'attribute_pa_' . sanitize_title( $attribute['attribute_name'] ) ), - array( 'meta_key' => 'attribute_pa_' . sanitize_title( $old_attribute_name ) ) - ); - } - echo '

                ' . __( 'Attribute updated successfully', 'woocommerce' ) . '

                ' . __( 'Back to Attributes', 'woocommerce' ) . '

                '; - wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); - delete_transient( 'wc_attribute_taxonomies' ); - return true; } /** * Delete an attribute. + * * @return bool */ private static function process_delete_attribute() { - global $wpdb; - $attribute_id = absint( $_GET['delete'] ); - check_admin_referer( 'woocommerce-delete-attribute_' . $attribute_id ); - $attribute_name = $wpdb->get_var( "SELECT attribute_name FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = $attribute_id" ); - $taxonomy = wc_attribute_taxonomy_name( $attribute_name ); - - do_action( 'woocommerce_before_attribute_delete', $attribute_id, $attribute_name, $taxonomy ); - - if ( $attribute_name && $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = $attribute_id" ) ) { - if ( taxonomy_exists( $taxonomy ) ) { - $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' ); - foreach ( $terms as $term ) { - wp_delete_term( $term->term_id, $taxonomy ); - } - } - - do_action( 'woocommerce_attribute_deleted', $attribute_id, $attribute_name, $taxonomy ); - delete_transient( 'wc_attribute_taxonomies' ); - return true; - } - - return false; + return wc_delete_attribute( $attribute_id ); } /** From 1a9b499be8c032d6c903e51f7a6bb4ef3eeb3a19 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 7 Aug 2017 22:14:10 -0300 Subject: [PATCH 123/127] Apply attribute helper functions to importers and REST API --- includes/admin/class-wc-admin-importers.php | 16 +-- ...-wc-rest-product-attributes-controller.php | 123 ++++-------------- .../import/abstract-wc-product-importer.php | 54 ++++---- 3 files changed, 55 insertions(+), 138 deletions(-) diff --git a/includes/admin/class-wc-admin-importers.php b/includes/admin/class-wc-admin-importers.php index 4a4afb4eb98..43d88fa4d66 100644 --- a/includes/admin/class-wc-admin-importers.php +++ b/includes/admin/class-wc-admin-importers.php @@ -158,15 +158,13 @@ class WC_Admin_Importers { // Create the taxonomy if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies() ) ) { - $attribute = array( - 'attribute_label' => $attribute_name, - 'attribute_name' => $attribute_name, - 'attribute_type' => 'select', - 'attribute_orderby' => 'menu_order', - 'attribute_public' => 0, - ); - $wpdb->insert( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute ); - delete_transient( 'wc_attribute_taxonomies' ); + wc_create_attribute( array( + 'name' => $attribute_name, + 'slug' => $attribute_name, + 'type' => 'select', + 'order_by' => 'menu_order', + 'has_archives' => false, + ) ); } // Register the taxonomy now so that the import works! diff --git a/includes/api/v1/class-wc-rest-product-attributes-controller.php b/includes/api/v1/class-wc-rest-product-attributes-controller.php index 32fe92f5189..e4290657e1d 100644 --- a/includes/api/v1/class-wc-rest-product-attributes-controller.php +++ b/includes/api/v1/class-wc-rest-product-attributes-controller.php @@ -240,38 +240,20 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { global $wpdb; - $args = array( - 'attribute_label' => $request['name'], - 'attribute_name' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'attribute_type' => ! empty( $request['type'] ) ? $request['type'] : 'select', - 'attribute_orderby' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', - 'attribute_public' => true === $request['has_archives'], - ); - - // Set the attribute slug. - if ( empty( $args['attribute_name'] ) ) { - $args['attribute_name'] = wc_sanitize_taxonomy_name( stripslashes( $args['attribute_label'] ) ); - } else { - $args['attribute_name'] = preg_replace( '/^pa\_/', '', wc_sanitize_taxonomy_name( stripslashes( $args['attribute_name'] ) ) ); - } - - $valid_slug = $this->validate_attribute_slug( $args['attribute_name'], true ); - if ( is_wp_error( $valid_slug ) ) { - return $valid_slug; - } - - $insert = $wpdb->insert( - $wpdb->prefix . 'woocommerce_attribute_taxonomies', - $args, - array( '%s', '%s', '%s', '%s', '%d' ) - ); + $id = wc_create_attribute( array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', + 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', + 'has_archives' => true === $request['has_archives'], + ) ); // Checks for errors. - if ( is_wp_error( $insert ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', $insert->get_error_message(), array( 'status' => 400 ) ); + if ( is_wp_error( $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); } - $attribute = $this->get_attribute( $wpdb->insert_id ); + $attribute = $this->get_attribute( $id ); if ( is_wp_error( $attribute ) ) { return $attribute; @@ -294,10 +276,6 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { $response->set_status( 201 ); $response->header( 'Location', rest_url( '/' . $this->namespace . '/' . $this->rest_base . '/' . $attribute->attribute_id ) ); - // Clear transients. - $this->flush_rewrite_rules(); - delete_transient( 'wc_attribute_taxonomies' ); - return $response; } @@ -329,48 +307,17 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { global $wpdb; $id = (int) $request['id']; - $format = array( '%s', '%s', '%s', '%s', '%d' ); - $args = array( - 'attribute_label' => $request['name'], - 'attribute_name' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'attribute_type' => $request['type'], - 'attribute_orderby' => $request['order_by'], - 'attribute_public' => $request['has_archives'], - ); + $edited = wc_update_attribute( $id, array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => $request['type'], + 'order_by' => $request['order_by'], + 'has_archives' => $request['has_archives'], + ) ); - $i = 0; - foreach ( $args as $key => $value ) { - if ( empty( $value ) && ! is_bool( $value ) ) { - unset( $args[ $key ] ); - unset( $format[ $i ] ); - } - - $i++; - } - - // Set the attribute slug. - if ( ! empty( $args['attribute_name'] ) ) { - $args['attribute_name'] = preg_replace( '/^pa\_/', '', wc_sanitize_taxonomy_name( stripslashes( $args['attribute_name'] ) ) ); - - $valid_slug = $this->validate_attribute_slug( $args['attribute_name'], false ); - if ( is_wp_error( $valid_slug ) ) { - return $valid_slug; - } - } - - if ( $args ) { - $update = $wpdb->update( - $wpdb->prefix . 'woocommerce_attribute_taxonomies', - $args, - array( 'attribute_id' => $id ), - $format, - array( '%d' ) - ); - - // Checks for errors. - if ( false === $update ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Could not edit the attribute.', 'woocommerce' ), array( 'status' => 400 ) ); - } + // Checks for errors. + if ( is_wp_error( $edited ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); } $attribute = $this->get_attribute( $id ); @@ -393,10 +340,6 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $attribute, $request ); - // Clear transients. - $this->flush_rewrite_rules(); - delete_transient( 'wc_attribute_taxonomies' ); - return rest_ensure_response( $response ); } @@ -407,8 +350,6 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { * @return WP_REST_Response|WP_Error */ public function delete_item( $request ) { - global $wpdb; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for this type, error out. @@ -425,25 +366,12 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $attribute, $request ); - $deleted = $wpdb->delete( - $wpdb->prefix . 'woocommerce_attribute_taxonomies', - array( 'attribute_id' => $attribute->attribute_id ), - array( '%d' ) - ); + $deleted = wc_delete_attribute( $attribute->attribute_id ); if ( false === $deleted ) { return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } - $taxonomy = wc_attribute_taxonomy_name( $attribute->attribute_name ); - - if ( taxonomy_exists( $taxonomy ) ) { - $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' ); - foreach ( $terms as $term ) { - wp_delete_term( $term->term_id, $taxonomy ); - } - } - /** * Fires after a single attribute is deleted via the REST API. * @@ -453,13 +381,6 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); - // Fires woocommerce_attribute_deleted hook. - do_action( 'woocommerce_attribute_deleted', $attribute->attribute_id, $attribute->attribute_name, $taxonomy ); - - // Clear transients. - $this->flush_rewrite_rules(); - delete_transient( 'wc_attribute_taxonomies' ); - return $response; } @@ -636,6 +557,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { /** * Validate attribute slug. * + * @deprecated 3.2.0 * @param string $slug * @param bool $new_data * @return bool|WP_Error @@ -655,6 +577,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { /** * Schedule to flush rewrite rules. * + * @deprecated 3.2.0 * @since 3.0.0 */ protected function flush_rewrite_rules() { diff --git a/includes/import/abstract-wc-product-importer.php b/includes/import/abstract-wc-product-importer.php index 251139d29fa..e7ce0cfb359 100644 --- a/includes/import/abstract-wc-product-importer.php +++ b/includes/import/abstract-wc-product-importer.php @@ -586,43 +586,39 @@ abstract class WC_Product_Importer implements WC_Importer_Interface { } // If the attribute does not exist, create it. - $args = array( - 'attribute_label' => $raw_name, - 'attribute_name' => $attribute_name, - 'attribute_type' => 'select', - 'attribute_orderby' => 'menu_order', - 'attribute_public' => 0, - ); + $attribute_id = wc_create_attribute( array( + 'name' => $raw_name, + 'slug' => $attribute_name, + 'type' => 'select', + 'order_by' => 'menu_order', + 'has_archives' => false, + ) ); - // Validate attribute. - if ( strlen( $attribute_name ) >= 28 ) { - throw new Exception( sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $attribute_name ), 400 ); - } elseif ( wc_check_if_attribute_name_is_reserved( $attribute_name ) ) { - throw new Exception( sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $attribute_name ), 400 ); - } elseif ( taxonomy_exists( wc_attribute_taxonomy_name( $attribute_name ) ) ) { - throw new Exception( sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $attribute_name ), 400 ); + if ( is_wp_error( $attribute_id ) ) { + throw new Exception( $attribute_id->get_error_message(), 400 ); } - $result = $wpdb->insert( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $args, array( '%s', '%s', '%s', '%s', '%d' ) ); - - // Pass errors. - if ( is_wp_error( $result ) ) { - throw new Exception( $result->get_error_message(), 400 ); - } - - $attribute_id = absint( $wpdb->insert_id ); - - // Delete transient. - delete_transient( 'wc_attribute_taxonomies' ); - // Register as taxonomy while importing. - register_taxonomy( wc_attribute_taxonomy_name( $attribute_name ), array( 'product' ), array( 'labels' => array( 'name' => $raw_name ) ) ); + $taxonomy_name = wc_attribute_taxonomy_name( $attribute_name ); + register_taxonomy( + $taxonomy_name, + apply_filters( 'woocommerce_taxonomy_objects_' . $taxonomy_name, array( 'product' ) ), + apply_filters( 'woocommerce_taxonomy_args_' . $taxonomy_name, array( + 'labels' => array( + 'name' => $raw_name, + ), + 'hierarchical' => true, + 'show_ui' => false, + 'query_var' => true, + 'rewrite' => false, + ) ) + ); // Set product attributes global. $wc_product_attributes = array(); - foreach ( wc_get_attribute_taxonomies() as $tax ) { - $wc_product_attributes[ wc_attribute_taxonomy_name( $attribute_name ) ] = $tax; + foreach ( wc_get_attribute_taxonomies() as $taxonomy ) { + $wc_product_attributes[ wc_attribute_taxonomy_name( $taxonomy['attribute_name'] ) ] = $taxonomy; } return $attribute_id; From 684a2b22ed94d887fd771fa2d1b3b855b163be1e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 8 Aug 2017 11:07:36 +0100 Subject: [PATCH 124/127] typo --- includes/wc-attribute-functions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 984781414e5..f64e6400c34 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -479,7 +479,7 @@ function wc_create_attribute( $args ) { return new WP_Error( 'cannot_update_attribute', __( 'Could not update the attribute.', 'woocommerce' ), array( 'status' => 400 ) ); } - // Set old_slug to check for database chances. + // Set old_slug to check for database changes. $args['old_slug'] = ! empty( $args['old_slug'] ) ? $args['old_slug'] : $args['slug']; /** @@ -582,7 +582,7 @@ function wc_delete_attribute( $id ) { $taxonomy = wc_attribute_taxonomy_name( $name ); /** - * Before delete an attribute. + * Before deleting an attribute. * * @param int $id Attribute ID. * @param string $name Attribute name. @@ -599,7 +599,7 @@ function wc_delete_attribute( $id ) { } /** - * After delete an attribute. + * After deleting an attribute. * * @param int $id Attribute ID. * @param string $name Attribute name. From 735a277e52fa96f7cb3b028103d679767d2dbacd Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 8 Aug 2017 12:44:36 +0100 Subject: [PATCH 125/127] initial state --- assets/js/admin/meta-boxes-product.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/assets/js/admin/meta-boxes-product.js b/assets/js/admin/meta-boxes-product.js index 31a6882a76a..89ae7f04bbf 100644 --- a/assets/js/admin/meta-boxes-product.js +++ b/assets/js/admin/meta-boxes-product.js @@ -238,6 +238,15 @@ jQuery( function( $ ) { }).change(); // DATE PICKER FIELDS. + function date_picker_select( datepicker ) { + var option = $( datepicker ).next().is( '.hasDatepicker' ) ? 'minDate' : 'maxDate', + otherDateField = 'minDate' === option ? $( datepicker ).next() : $( datepicker ).prev(), + date = $( datepicker ).datepicker( 'getDate' ); + + $( otherDateField ).datepicker( 'option', option, date ); + $( datepicker ).change(); + } + $( '.sale_price_dates_fields' ).each( function() { $( this ).find( 'input' ).datepicker({ defaultDate: '', @@ -245,14 +254,10 @@ jQuery( function( $ ) { numberOfMonths: 1, showButtonPanel: true, onSelect: function() { - var option = $( this ).next().is('.hasDatepicker') ? 'minDate' : 'maxDate', - dates = $( this ).closest( '.sale_price_dates_fields' ).find( 'input' ), - date = $( this ).datepicker( 'getDate' ); - - dates.not( this ).datepicker( 'option', option, date ); - $( this ).change(); + date_picker_select( $( this ) ); } }); + $( this ).find( 'input' ).each( function() { date_picker_select( $( this ) ) } ); }); // ATTRIBUTE TABLES. From 2f6aaa85bb2e83bcd223d850b50b8175c5188901 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 8 Aug 2017 13:04:27 +0100 Subject: [PATCH 126/127] Avoid using meta directly --- includes/class-wc-customer.php | 22 ++++++++++++++++++++++ includes/wc-account-functions.php | 30 +++++++++--------------------- templates/myaccount/my-address.php | 8 +++----- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/includes/class-wc-customer.php b/includes/class-wc-customer.php index e12916886a6..ae3e368cb3a 100644 --- a/includes/class-wc-customer.php +++ b/includes/class-wc-customer.php @@ -439,6 +439,17 @@ class WC_Customer extends WC_Legacy_Customer { return $value; } + /** + * Get billing. + * + * @since 3.2.0 + * @param string $context + * @return array + */ + public function get_billing( $context = 'view' ) { + return $this->get_prop( 'billing', $context ); + } + /** * Get billing_first_name. * @@ -559,6 +570,17 @@ class WC_Customer extends WC_Legacy_Customer { return $this->get_address_prop( 'phone', 'billing', $context ); } + /** + * Get shipping. + * + * @since 3.2.0 + * @param string $context + * @return array + */ + public function get_shipping( $context = 'view' ) { + return $this->get_prop( 'shipping', $context ); + } + /** * Get shipping_first_name. * diff --git a/includes/wc-account-functions.php b/includes/wc-account-functions.php index 20a35a3adbb..aabb09b45ba 100644 --- a/includes/wc-account-functions.php +++ b/includes/wc-account-functions.php @@ -244,30 +244,18 @@ function wc_get_account_payment_methods_types() { * Get account formatted address. * * @since 3.2.0 - * @param string $name + * @param string $address_type billing or shipping. * @return string */ -function wc_get_account_formatted_address( $name ) { - $customer_id = get_current_user_id(); - $meta_keys = [ - 'first_name', - 'last_name', - 'company', - 'address_1', - 'address_2', - 'city', - 'postcode', - 'country', - ]; - - $meta = []; - foreach ( $meta_keys as $key ) { - $meta[ $key ] = get_user_meta( $customer_id, $name . '_' . $key, true ); +function wc_get_account_formatted_address( $address_type ) { + $getter = "get_{$address_type}"; + $customer = new WC_Customer( get_current_user_id() ); + + if ( is_callable( array( $customer, $getter ) ) ) { + $address = $customer->$getter(); + unset( $address['email'], $address['tel'] ); } - - $address = apply_filters( 'woocommerce_my_account_my_address_formatted_address', $meta, $customer_id, $name ); - - return WC()->countries->get_formatted_address( $address ); + return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_my_account_my_address_formatted_address', $address, $customer->get_id(), $address_type ) ); } /** diff --git a/templates/myaccount/my-address.php b/templates/myaccount/my-address.php index 420c414ceca..6ef25a84e39 100644 --- a/templates/myaccount/my-address.php +++ b/templates/myaccount/my-address.php @@ -52,12 +52,10 @@ $col = 1;

                -
                - -
                + echo $address ? wp_kses_post( $address ) : esc_html_e( 'You have not set up this type of address yet.', 'woocommerce' ); + ?> From 396faa19d73d1655712ce853e18456882792163b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 8 Aug 2017 15:25:32 +0100 Subject: [PATCH 127/127] phpcs --- includes/class-wc-meta-data.php | 41 +++++++++++++++++---------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/includes/class-wc-meta-data.php b/includes/class-wc-meta-data.php index 41595e1055a..b1830b5468b 100644 --- a/includes/class-wc-meta-data.php +++ b/includes/class-wc-meta-data.php @@ -1,43 +1,47 @@ current_data = $meta; $this->apply_changes(); } @@ -52,9 +56,8 @@ class WC_Meta_Data { /** * Creates or updates a property in the metadata object. * - * @param string $key - * @param mixed $value - * + * @param string $key Key to set. + * @param mixed $value Value to set. */ public function __set( $key, $value ) { $this->current_data[ $key ] = $value; @@ -64,7 +67,7 @@ class WC_Meta_Data { * Checks if a given key exists in our data. This is called internally * by `empty` and `isset`. * - * @param string $key + * @param string $key Key to check if set. */ public function __isset( $key ) { return array_key_exists( $key, $this->current_data ); @@ -73,8 +76,7 @@ class WC_Meta_Data { /** * Returns the value of any property. * - * @param string $key - * + * @param string $key Key to get. * @return mixed Property value or NULL if it does not exists */ public function __get( $key ) { @@ -96,7 +98,6 @@ class WC_Meta_Data { $changes[ $id ] = $value; } } - return $changes; }