Add custom field to product inventory tab and display value on single product page where meta ends - wordpress

I'm using the following code in my theme functions.php file to add a additional data field to the product inventory tab:
// Add Custom Field to woocommerce inventory tab for product
add_action('woocommerce_product_options_inventory_product_data', function() {
woocommerce_wp_text_input([
'id' => '_number_in_package',
'label' => __('Number of Pages', 'txtdomain'),
'type' => 'number',
]);
});
add_action('woocommerce_process_product_meta', function($post_id) {
$product = wc_get_product($post_id);
$num_package = isset($_POST['_number_in_package']) ? $_POST['_number_in_package'] : '';
$product->update_meta_data('_number_in_package', sanitize_text_field($num_package));
$product->save();
});
add_action('woocommerce_product_meta_start', function() {
global $post;
$product = wc_get_product($post->ID);
$num_package = $product->get_meta('_number_in_package');
if (!empty($num_package)) {
printf('<div class="custom-sku">%s: %s</div>', __('Number of Pages', 'txtdomain'), $num_package);
}
});
add_filter('woocommerce_product_data_tabs', function($tabs) {
$tabs['additional_info'] = [
'label' => __('Additional info', 'txtdomain'),
'target' => 'additional_product_data',
'class' => ['hide_if_external'],
'priority' => 25
];
return $tabs;
});
However, on the single product page, the custom field is added before category and ISBN. I want to place the custom field at the end after the product ISBN. Any advice?

Some comments/suggestions regarding your code attempt
To save fields you can use the woocommerce_admin_process_product_object hook, opposite the outdated woocommerce_process_product_meta hook
WooCommerce contains by default no ISBN field, but it looks like the woocommerce_product_meta_end hook will answer your question
So you get:
// Add custom field
function action_woocommerce_product_options_inventory_product_data() {
woocommerce_wp_text_input( array(
'id' => '_number_in_package',
'label' => __( 'Number of Pages', 'woocommerce' ),
'description' => __( 'This is a custom field, you can write here anything you want.', 'woocommerce' ),
'desc_tip' => 'true',
'type' => 'number'
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'action_woocommerce_product_options_inventory_product_data' );
// Save custom field
function action_woocommerce_admin_process_product_object( $product ) {
// Isset
if ( isset( $_POST['_number_in_package'] ) ) {
// Update
$product->update_meta_data( '_number_in_package', sanitize_text_field( $_POST['_number_in_package'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
// Display on single product page
function action_woocommerce_product_meta_end() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Get meta
$number = $product->get_meta( '_number_in_package' );
// NOT empty
if ( ! empty ( $number ) ) {
echo '<p>' . $number . '</p>';
}
}
}
add_action( 'woocommerce_product_meta_end', 'action_woocommerce_product_meta_end', 10 );

Related

How to add custom button before Add to Cart form in WooCommerce Product Page and I want different links for different products?

How to add a custom button before Add to Cart form on WooCommerce Product Page? and I want different links for different products.
My PHP Code:
add_action( 'woocommerce_before_add_to_cart_form', 'learnalwayss_after_add_to_cart_btn' );
function learnalwayss_after_add_to_cart_btn() {
global $product;
if ( $product->get_id() == 149685 ) {
echo '<a class="button primary is-small box-shadow-4 box-shadow-2-hover" style="border-radius: 10px; background-color:#FFDB58 !important; color:black;" target="_blank" href="https://myurls.bio/learn_alwayss">Our Links</a>';
}
}
Your solution is simple and effective but you have to add every url manually in the source code.
The solution I am suggesting uses wp_postmeta to store the label and url of the button. This way, a regular user can add/change the value of the url instead of asking a developer to make every change.
We'll add 2 custom fields to the product page to store these values into metadata.
To add custom fields for the custom_button_url and custom_button_text metadata to the edit product page in WooCommerce, you can use the woocommerce_product_options_general_product_data hook to add the custom fields to the product data panel, and the woocommerce_process_product_meta hook to save the custom field values when the product is saved.
function custom_button_product_data_fields() {
global $post;
// Get the values of the "custom_button_url" and "custom_button_text" custom fields
$custom_button_url = get_post_meta( $post->ID, 'custom_button_url', true );
$custom_button_text = get_post_meta( $post->ID, 'custom_button_text', true );
// Add a custom field for the "custom_button_url" metadata
woocommerce_wp_text_input( array(
'id' => 'custom_button_url',
'label' => __( 'Custom Button URL', 'your-text-domain' ),
'placeholder' => 'http://',
'description' => __( 'Enter the URL for the custom button.', 'your-text-domain' ),
'type' => 'url',
'value' => $custom_button_url,
'custom_attributes' => array(
'pattern' => 'https?://.+',
),
) );
// Add a custom field for the "custom_button_text" metadata
woocommerce_wp_text_input( array(
'id' => 'custom_button_text',
'label' => __( 'Custom Button Text', 'your-text-domain' ),
'placeholder' => '',
'description' => __( 'Enter the text for the custom button.', 'your-text-domain' ),
'type' => 'text',
'value' => $custom_button_text,
) );
}
add_action( 'woocommerce_product_options_general_product_data', 'custom_button_product_data_fields' );
And to save the values into the wp_postmeta you can use woocommerce_process_product_meta hook
function save_custom_button_product_data_fields( $post_id ) {
// Save the value of the "custom_button_url" custom field
$custom_button_url = isset( $_POST['custom_button_url'] ) ? sanitize_text_field( $_POST['custom_button_url'] ) : '';
update_post_meta( $post_id, 'custom_button_url', $custom_button_url );
// Save the value of the "custom_button_text" custom field
$custom_button_text = isset( $_POST['custom_button_text'] ) ? sanitize_text_field( $_POST['custom_button_text'] ) : '';
update_post_meta( $post_id, 'custom_button_text', $custom_button_text );
}
add_action( 'woocommerce_process_product_meta', 'save_custom_button_product_data_fields' );
Now we only have to display the button using the woocommerce_before_add_to_cart_form hook. You can use any other hook on the product page to show the button in a different place.
function custom_button_before_add_to_cart() {
global $product;
$product_id = $product->get_id();
// Get the values of the "custom_button_url" and "custom_button_text" custom fields
$custom_button_url = get_post_meta( $product_id, 'custom_button_url', true );
$custom_button_text = get_post_meta( $product_id, 'custom_button_text', true );
// If the "custom_button_url" custom field has a value, show the button
if ( ! empty( $custom_button_url ) ) {
// If the "custom_button_text" custom field has a value, use it as the button text
if ( ! empty( $custom_button_text ) ) {
$button_text = $custom_button_text;
} else {
// If the "custom_button_text" custom field is empty, use the default button text
$button_text = __( 'Default Button Text', 'your-text-domain' );
}
// Use the value of the "custom_button_url" custom field as the button link
$button_link = $custom_button_url;
echo '' . esc_html( $button_text ) . '';
}
}
add_action( 'woocommerce_before_add_to_cart_form', 'custom_button_before_add_to_cart' );
This code enables you to use WordPress or ACF custom fields to add unique button links.
add_action( 'woocommerce_before_add_to_cart_form', 'button_custom_field' );
function button_custom_field() {
$wp = get_post_meta( get_the_ID(), 'wp_button', true );
$acf = class_exists('acf') ? get_field('acf_button') : '';
$field = $acf ? $acf : $wp;
if ( $field && is_singular('product') ) {
printf( '' . __( 'Custom Button' ) . '', $field );
}
}
Note : I wouldn't add the styling inline. Better to add it in your child themes stylesheet. Source

Product query results are not correct

I need a custom fields on the inventory tab that will be filled in with the zipcode as the location of the agent.
Armed with the references I got here, now I have that field.
what I want to ask is how to concatenate this meta data with woocommerce shortcode?
I think like :
['products limit="12" columns="4" zipcode="12345"]
where "12345" will be changing dynamically as needed (zipcode filled based on agent location).
I have tried to do something but it is not working properly.
Here's the full code.
function action_woocommerce_product_options_inventory_product_data_zipcode() {
woocommerce_wp_text_input( array(
'id' => '_zipcode',
'label' => __( 'Zipcode', 'woocommerce' ),
'description' => __( 'Please fill your zipcode.', 'woocommerce' ),
'desc_tip' => 'true',
'placeholder' => __( '12345', 'woocommerce' )
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'action_woocommerce_product_options_inventory_product_data_zipcode' );
// Save zipcode
function action_woocommerce_admin_process_product_object_zipcode( $product ) {
// Isset
if ( isset( $_POST['_zipcode'] ) ) {
// Update
$product->update_meta_data( '_zipcode', sanitize_text_field( $_POST['_zipcode'] ));
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object_zipcode', 10, 1 );
Try put to shortcode products :
function filter_shortcode_atts_products_zipcode ( $out, $pairs, $atts, $shortcode) {
if ( isset ( $atts['zipcode'] ) && !empty($atts['zipcode']) ) {
$out['zipcode'] = true;
} else {
$out['zipcode'] = false;
}
return $out;
}
add_filter( 'shortcode_atts_products', 'filter_shortcode_atts_products_zipcode', 10, 4);
function filter_woocommerce_shortcode_products_query_zipcode( $query_args, $atts, $type) {
if ( $type == 'products' && $atts['zipcode'] ) {
// Meta query
$query_args['meta_query'] = array(
array(
'key' => '_zipcode',
'value' => $atts['zipcode'],
'compare' => 'LIKE',
)
);
}
return $query_args;
}
add_filter( 'woocommerce_shortcode_products_query', 'filter_woocommerce_shortcode_products_query_zipcode', 10, 3 );
On testing I tried :
['products limit="12" columns="4" zipcode="12345"]
shortcode has displayed the product but does not refer to the postal code in the short code ("12345") but to all products that have a postal code.
Can somebody help me?
Thank you
Something doesn't feel right about the shortcode attribute function. I think you're setting the attribute as true and therefore it's comparing anything "truthy." Maybe just try setting the true one as the zipcode, like this:
function filter_shortcode_atts_products_zipcode ( $out, $pairs, $atts, $shortcode) {
if ( isset ( $atts['zipcode'] ) && !empty($atts['zipcode']) ) {
$out['zipcode'] = $atts['zipcode'];
} else {
$out['zipcode'] = false;
}
return $out;
}
That way it'll return the zipcode if it exists, and false if it doesn't, which the query can then use for the comparison.

Add checkbox to product inventory tab in WooCommerce and have the checkbox checked by default

I got this snippet in here to add checkbox custom field which is auto set and it’s working fine.
// Displaying quantity setting fields on admin product pages
add_action( 'woocommerce_product_options_pricing', 'add_custom_field_product_options_pricing' );
function add_custom_field_product_options_pricing() {
global $product_object;
echo '</div><div class="options_group">';
$values = $product_object->get_meta('_cutom_meta_key');
woocommerce_wp_checkbox( array( // Checkbox.
'id' => '_cutom_meta_key',
'label' => __( 'Custom label', 'woocommerce' ),
'value' => empty($values) ? 'yes' : $values,
'description' => __( 'Enable this to make something.', 'woocommerce' ),
) );
}
// Save quantity setting fields values
add_action( 'woocommerce_admin_process_product_object', 'save_custom_field_product_options_pricing' );
function save_custom_field_product_options_pricing( $product ) {
$product->update_meta_data( '_cutom_meta_key', isset($_POST['_cutom_meta_key']) ? 'yes' : 'no');
}
My question: how to move this checkbox to be on the inventory tab and have the checkbox checked by default?
I’ve tried changing :
add_action( 'woocommerce_product_options_pricing', 'add_custom_field_product_options_pricing' );
to:
add_action( 'woocommerce_product_options_inventory_product_data', 'add_custom_field_product_options_pricing' );
AND
add_action( 'woocommerce_admin_process_product_object', 'save_custom_field_product_options_pricing' );
to:
add_action( 'woocommerce_process_product_meta', 'save_custom_field_product_options_pricing' );
But to no avail. Any advice?
woocommerce_admin_process_product_object replaces the outdated woocommerce_process_product_meta hook so you should definitely not replace it with it
To have the checkbox checked by default you can add value to the args from woocommerce_wp_checkbox()
So you get:
// Add checkbox
function action_woocommerce_product_options_inventory_product_data() {
global $product_object;
// Get meta
$value = $product_object->get_meta( '_cutom_meta_key' );
// Checkbox
woocommerce_wp_checkbox( array(
'id' => '_cutom_meta_key', // Required, it's the meta_key for storing the value (is checked or not)
'label' => __( 'Custom label', 'woocommerce' ), // Text in the editor label
'desc_tip' => false, // true or false, show description directly or as tooltip
'description' => __( 'Enable this to make something', 'woocommerce' ), // Provide something useful here
'value' => empty( $value ) ? 'yes' : $value // Checked by default
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'action_woocommerce_product_options_inventory_product_data', 10, 0 );
// Save Field
function action_woocommerce_admin_process_product_object( $product ) {
// Update meta
$product->update_meta_data( '_cutom_meta_key', isset( $_POST['_cutom_meta_key'] ) ? 'yes' : 'no' );
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );

Display custom checkout field value on admin order detail section in Woocommerce

Hello I'm trying to display the custom checkout field in the admin order details page. My Custom field is Delivery Option and it allows the user to pick the to pick a value from checkbox. I use the code below following the similar topics about this, but it seems something is wrong with my code.
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_additional_field', 20 );
function checkout_shipping_additional_field()
{
$domain = 'wocommerce';
$default = 'option 1';
echo '<tr class="additional-shipping-fields"><th>' . __('Delivery Time', $domain) . '</th><td>';
// Add a custom checkbox field
woocommerce_form_field( 'custom_radio_field', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'options' => array(
'option 1' => __('10:04 : 13:04 ', $domain),
),
'default' => $default,
), $default );
echo '</td></tr>';
}
//update order meta
add_action('woocommerce_checkout_update_order_meta', 'gon_update_order_meta_business_address');
function gon_update_order_meta_business_address( $order_id ) {
if ($_POST['custom_radio_field']) update_post_meta( $order_id, 'Business Address?',
esc_attr($_POST['custom_radio_field']));
}
// Display field value on the admin order edit page
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
function custom_checkout_field_display_admin_order_meta( $order ){
$delivery_time = get_post_meta( $order->get_id(), 'Delivery Time', true );
if( ! empty( $delivery_time ) )
echo '<p><strong>'.__('Delivery Time', 'woocommerce').': </strong> ' . $delivery_time . '</p>';
}
There is some mistakes, so I have revisited your code. I have also replaced some hooks. Try the following:
// HERE set your the options array for your select field.
function delivery_time_options(){
$domain = 'woocommerce';
return array(
'1' => __('10:04 : 13:04 ', $domain),
'2' => __('14:04 : 16:04 ', $domain), // <== Added for testing
);
}
// Display a custom select field after shipping total line
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_additional_field', 20 );
function checkout_shipping_additional_field(){
$domain = 'woocommerce';
echo '<tr class="additional-shipping-fields"><th>' . __('Delivery Time', $domain) . '</th><td>';
// Add a custom select field
woocommerce_form_field( 'delivery_time', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'options' => delivery_time_options(),
), '' );
echo '</td></tr>';
}
// Save custom field as order meta data
add_action('woocommerce_checkout_create_order', 'save_custom_field_order_meta', 22, 2 );
function save_custom_field_order_meta( $order, $data ) {
if ( isset($_POST['delivery_time']) ) {
$options = delivery_time_options(); // Get select options array
$option_key = esc_attr($_POST['delivery_time']); // The selected key
$order->update_meta_data( '_delivery_time', $options[$option_key] ); // Save
}
}
// Display a custom field value on the admin order edit page
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_custom_meta_data_in_backend_orders', 10, 1 );
function display_custom_meta_data_in_backend_orders( $order ){
$domain = 'woocommerce';
$delivery_time = $order->get_meta('_delivery_time');
if( ! empty( $delivery_time ) )
echo '<p><strong>'.__('Delivery Time', $domain).': </strong> ' . $delivery_time . '</p>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Based on #LoicTheAztec answer, if you want multiple fields without re-writing the functions for every field (DRY), you can use this class (by adding it to your functions.php):
/**
* Add a custom field to the woocommerce checkout page
* https://stackoverflow.com/q/52098807/
*/
class WOO_Add_Checkout_Field
{
public function __construct($options)
{
$this->field_name = $options['field_name'];
$this->label = $options['label'];
$this->placeholder = $options['placeholder'];
$this->required = $options['required'];
if ($this->field_name && $this->label && $this->placeholder) {
add_action('woocommerce_after_order_notes', [$this, 'customise_checkout_field']);
add_action('woocommerce_checkout_update_order_meta', [$this, 'custom_checkout_field_update_order_meta'], 10, 1);
add_action('woocommerce_admin_order_data_after_billing_address', [$this, 'display_custom_field_on_order_edit_pages'], 10, 1);
} else {
die("Error in WOO_Add_Checkout_Field \$options: \n\n" . var_dump($options));
}
}
public function customise_checkout_field($checkout)
{
echo '<div id="customise_checkout_field">';
// echo '<h2>' . __('Heading') . '</h2>';
woocommerce_form_field($this->field_name, array(
'type' => 'text',
'class' => array(
'my-field-class form-row-wide'
),
'label' => $this->label,
'placeholder' => $this->placeholder,
'required' => $this->required,
), $checkout->get_value($this->field_name));
echo '</div>';
}
public function custom_checkout_field_update_order_meta($order_id)
{
if (!empty($_POST[$this->field_name]))
update_post_meta($order_id, $this->field_name, $_POST[$this->field_name]);
else
update_post_meta($order_id, $this->field_name, 0);
}
public function display_custom_field_on_order_edit_pages($order)
{
$field = $order->get_meta($this->field_name);
if (!empty($field)) {
echo '<p><strong style="display:block" title="' . $this->placeholder . '">' . $this->label . ': </strong><span>';
echo $field;
echo '</span></p>';
}
}
}
And use it as many times as you'd like:
$my_custom_field_1 = new WOO_Add_Checkout_Field([
'field_name' => 'my_custom_field_1',
'label' => __('My First Field'),
'placeholder' => __('Please write something in field 1...'),
'required' => false,
]);
$my_custom_field_2 = new WOO_Add_Checkout_Field([
'field_name' => 'my_custom_field_2',
'label' => __('My Second Field'),
'placeholder' => __('Please write something in field 2...'),
'required' => false,
]);
$my_custom_field_3 = new WOO_Add_Checkout_Field([
'field_name' => 'my_custom_field_3',
'label' => __('My Third Field'),
'placeholder' => __('Please write something in field 3...'),
'required' => false,
]);
// and so on...
Please note:
The custom field will show up in admin area ONLY if it was not sent empty
You can customize this code how you like

Update user meta after woocommerce checkout form process

I am using woocommerce with Wordpress and have added some custom fields to the checkout:
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
$extra_fields = array('job_title', 'company', 'telephone', 'occupation');
foreach($extra_fields as $key => $value) {
woocommerce_form_field($value, array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __($label),
'value' => '',
), $checkout->get_value( $value ));
}
}
Now currently, these appear in the checkout fine, not sure if using woocommerce_after_order_notes is right in this case. I have also added some custom fields to the user meta that correspond to the fields added to the checkout - which all display in the user profile page:
function add_contact_methods( $contactmethods ) {
$contactmethods['job_title'] = 'Job Title';
$contactmethods['company'] = 'Company Name';
$contactmethods['telephone'] = 'Telephone';
$contactmethods['occupation'] = 'Occupation';
$contactmethods['refer'] = 'How you heard about us?';
return $contactmethods;
}
add_filter('user_contactmethods','add_contact_methods',10,1);
As you can imagine, if I update any of these field in any profile page, it works fine but what I cant seem to do is update the user meta when a new user makes a purchase, it does not update the user meta for these fields in the database.
I understand alot of how this works, and understand that I must hook into a Woocommerce process to add the fields into the process. So I have added this code into my functions too:
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
global $extra_fields;
foreach($extra_fields as $key => $value) {
if ($_POST[$value]) update_user_meta( $user_id, $value, esc_attr($_POST[$value]));
}
}
Now the twist is, this works if a user who is already signed in as a member, makes a repurchase and goes through the checkout - the reason this works is because $user_id already exists, but when a new user is checking out, they do not yet exist as a user, hence the function cannot update the user meta of NIL where $user_id does not exist.
My question is, how do I hook into the checkout process, presumably AFTER the user has been created, so I that I can get the $user_id returned, and execute this function to update the user meta.
class-wc-checkout.php line 639 creates the new user with $this->customer_id = wp_insert_user( apply_filters( 'woocommerce_new_customer_data', $new_customer_data ) ); The new customer data is an array listed just above that line.
Following that, you can access the user id with line 649's action do_action( 'woocommerce_created_customer', $this->customer_id );
It is unlikey, in your case, you will need to use the filter, but simply add the action 'woocommerce_created_customer', pull in the id, and add the meta.
When customer is not logged in checkout page should be acceptable field customer want to create a new account.Below sample code change in checkout page when customer order a new item and update user meta data.
function user_extra_meta_fields(){
return array(
'job_title' => __( 'Job Title', 'yourtext_domain'),
'company' => __( 'Company Name', 'yourtext_domain'),
'telephone' => __( 'Telephone', 'yourtext_domain'),
'occupation' => __( 'Occupation', 'yourtext_domain'),
'refer' => __( 'How you heard about us?', 'yourtext_domain'),
);
}
function add_contact_methods( $contactmethods ) {
$contactmethods = array_merge( $contactmethods, user_extra_meta_fields());
return $contactmethods;
}
add_filter('user_contactmethods','add_contact_methods',10,1);
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
foreach( user_extra_meta_fields() as $name => $label) {
$value = '';
if( is_user_logged_in() )
$value = get_user_meta( get_current_user_id(), $name, true );
woocommerce_form_field( $name, array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => $label,
), $value );
}
}
add_action( 'woocommerce_checkout_process', 'user_fields_woocommerce_checkout_process' );
function user_fields_woocommerce_checkout_process(){
if( is_user_logged_in() )
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta' );
else
add_action( 'woocommerce_created_customer', 'my_custom_checkout_field_update_user_meta' );
}
function my_custom_checkout_field_update_user_meta( $user_id ) {
foreach( array_keys( user_extra_meta_fields() ) as $meta_name ){
if( isset( $_POST[$meta_name] ) ){
$meta_value = $_POST[$meta_name] ? esc_attr($_POST[$meta_name]) : '';
update_user_meta( $user_id, $meta_name, $meta_value );
}
}
}
// if want to validate field
add_action( 'woocommerce_after_checkout_validation', 'user_fields_woocommerce_after_checkout_validation' );
function user_fields_woocommerce_after_checkout_validation( $posted ){
$validate = true;
if( ! is_user_logged_in() && empty( $posted['createaccount'] ) )
$validate = false;
if( $validate == false )
return;
$meta_data = user_extra_meta_fields();
foreach( array_keys( $meta_data ) as $meta_name ){
if( empty($_POST[$meta_name]) )
wc_add_notice( sprintf( __(' <strong>%s</strong> is required.', 'yourtext_domain'), $meta_data[$meta_name] ), 'error' );
}
}

Resources