/** * Add Attribute admin panel * * Shows the interface for adding new attributes */ public static function add_attribute() { ?> <div class="wrap woocommerce"> <div class="icon32 icon32-attributes" id="icon-woocommerce"><br/></div> <h2><?php _e('Attributes', 'woocommerce'); ?> </h2> <br class="clear" /> <div id="col-container"> <div id="col-right"> <div class="col-wrap"> <table class="widefat attributes-table wp-list-table ui-sortable" style="width:100%"> <thead> <tr> <th scope="col"><?php _e('Name', 'woocommerce'); ?> </th> <th scope="col"><?php _e('Slug', 'woocommerce'); ?> </th> <th scope="col"><?php _e('Type', 'woocommerce'); ?> </th> <th scope="col"><?php _e('Order by', 'woocommerce'); ?> </th> <th scope="col" colspan="2"><?php _e('Terms', 'woocommerce'); ?> </th> </tr> </thead> <tbody> <?php if ($attribute_taxonomies = wc_get_attribute_taxonomies()) { foreach ($attribute_taxonomies as $tax) { ?> <tr> <td> <strong><a href="edit-tags.php?taxonomy=<?php echo esc_html(wc_attribute_taxonomy_name($tax->attribute_name)); ?> &post_type=product"><?php echo esc_html($tax->attribute_label); ?> </a></strong> <div class="row-actions"><span class="edit"><a href="<?php echo esc_url(add_query_arg('edit', $tax->attribute_id, 'edit.php?post_type=product&page=product_attributes')); ?> "><?php _e('Edit', 'woocommerce'); ?> </a> | </span><span class="delete"><a class="delete" href="<?php echo esc_url(wp_nonce_url(add_query_arg('delete', $tax->attribute_id, 'edit.php?post_type=product&page=product_attributes'), 'woocommerce-delete-attribute_' . $tax->attribute_id)); ?> "><?php _e('Delete', 'woocommerce'); ?> </a></span></div> </td> <td><?php echo esc_html($tax->attribute_name); ?> </td> <td><?php echo esc_html(ucfirst($tax->attribute_type)); ?> <?php echo $tax->attribute_public ? '(' . __('Public', 'woocommerce') . ')' : ''; ?> </td> <td><?php switch ($tax->attribute_orderby) { case 'name': _e('Name', 'woocommerce'); break; case 'name_num': _e('Name (numeric)', 'woocommerce'); break; case 'id': _e('Term ID', 'woocommerce'); break; default: _e('Custom ordering', 'woocommerce'); break; } ?> </td> <td class="attribute-terms"><?php $taxonomy = wc_attribute_taxonomy_name($tax->attribute_name); if (taxonomy_exists($taxonomy)) { $terms = get_terms($taxonomy, 'hide_empty=0'); switch ($tax->attribute_orderby) { case 'name_num': usort($terms, '_wc_get_product_terms_name_num_usort_callback'); break; case 'parent': usort($terms, '_wc_get_product_terms_parent_usort_callback'); break; } $terms_string = implode(', ', wp_list_pluck($terms, 'name')); if ($terms_string) { echo $terms_string; } else { echo '<span class="na">–</span>'; } } else { echo '<span class="na">–</span>'; } ?> </td> <td class="attribute-actions"><a href="edit-tags.php?taxonomy=<?php echo esc_html(wc_attribute_taxonomy_name($tax->attribute_name)); ?> &post_type=product" class="button alignright tips configure-terms" data-tip="<?php esc_attr_e('Configure terms', 'woocommerce'); ?> "><?php _e('Configure terms', 'woocommerce'); ?> </a></td> </tr><?php } } else { ?> <tr><td colspan="6"><?php _e('No attributes currently exist.', 'woocommerce'); ?> </td></tr><?php } ?> </tbody> </table> </div> </div> <div id="col-left"> <div class="col-wrap"> <div class="form-wrap"> <h3><?php _e('Add New Attribute', 'woocommerce'); ?> </h3> <p><?php _e('Attributes let you define extra product data, such as size or colour. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woocommerce'); ?> </p> <form action="edit.php?post_type=product&page=product_attributes" method="post"> <div class="form-field"> <label for="attribute_label"><?php _e('Name', 'woocommerce'); ?> </label> <input name="attribute_label" id="attribute_label" type="text" value="" /> <p class="description"><?php _e('Name for the attribute (shown on the front-end).', 'woocommerce'); ?> </p> </div> <div class="form-field"> <label for="attribute_name"><?php _e('Slug', 'woocommerce'); ?> </label> <input name="attribute_name" id="attribute_name" type="text" value="" maxlength="28" /> <p class="description"><?php _e('Unique slug/reference for the attribute; must be shorter than 28 characters.', 'woocommerce'); ?> </p> </div> <div class="form-field"> <label for="attribute_public"><input name="attribute_public" id="attribute_public" type="checkbox" value="1" /> <?php _e('Enable Archives?', 'woocommerce'); ?> </label> <p class="description"><?php _e('Enable this if you want this attribute to have product archives in your store.', 'woocommerce'); ?> </p> </div> <div class="form-field"> <label for="attribute_type"><?php _e('Type', 'woocommerce'); ?> </label> <select name="attribute_type" id="attribute_type"> <?php foreach (wc_get_attribute_types() as $key => $value) { ?> <option value="<?php echo esc_attr($key); ?> "><?php echo esc_attr($value); ?> </option> <?php } ?> <?php /** * Deprecated action in favor of product_attributes_type_selector filter * * @deprecated 2.4.0 */ do_action('woocommerce_admin_attribute_types'); ?> </select> <p class="description"><?php _e('Determines how you select attributes for products. Under admin panel -> products -> product data -> attributes -> values, <strong>Text</strong> allows manual entry whereas <strong>select</strong> allows pre-configured terms in a drop-down list.', 'woocommerce'); ?> </p> </div> <div class="form-field"> <label for="attribute_orderby"><?php _e('Default sort order', 'woocommerce'); ?> </label> <select name="attribute_orderby" id="attribute_orderby"> <option value="menu_order"><?php _e('Custom ordering', 'woocommerce'); ?> </option> <option value="name"><?php _e('Name', 'woocommerce'); ?> </option> <option value="name_num"><?php _e('Name (numeric)', 'woocommerce'); ?> </option> <option value="id"><?php _e('Term ID', 'woocommerce'); ?> </option> </select> <p class="description"><?php _e('Determines the sort order of the terms on the frontend shop product pages. If using custom ordering, you can drag and drop the terms in this attribute.', 'woocommerce'); ?> </p> </div> <p class="submit"><input type="submit" name="add_new_attribute" id="submit" class="button button-primary" value="<?php esc_attr_e('Add Attribute', 'woocommerce'); ?> "></p> <?php wp_nonce_field('woocommerce-add-new_attribute'); ?> </form> </div> </div> </div> </div> <script type="text/javascript"> /* <![CDATA[ */ jQuery( 'a.delete' ).click( function() { if ( window.confirm( '<?php _e("Are you sure you want to delete this attribute?", "woocommerce"); ?> ' ) ) { return true; } return false; }); /* ]]> */ </script> </div> <?php }
/** * Validate attribute data. * * @since 2.4.0 * @param string $name * @param string $slug * @param string $type * @param string $order_by * @param bool $new_data * @return bool */ protected function validate_attribute_data($name, $slug, $type, $order_by, $new_data = true) { if (empty($name)) { throw new WC_API_Exception('woocommerce_api_missing_product_attribute_name', sprintf(__('Missing parameter %s', 'woocommerce'), 'name'), 400); } if (strlen($slug) >= 28) { throw new WC_API_Exception('woocommerce_api_invalid_product_attribute_slug_too_long', sprintf(__('Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce'), $slug), 400); } else { if (wc_check_if_attribute_name_is_reserved($slug)) { throw new WC_API_Exception('woocommerce_api_invalid_product_attribute_slug_reserved_name', sprintf(__('Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce'), $slug), 400); } else { if ($new_data && taxonomy_exists(wc_attribute_taxonomy_name($slug))) { throw new WC_API_Exception('woocommerce_api_invalid_product_attribute_slug_already_exists', sprintf(__('Slug "%s" is already in use. Change it, please.', 'woocommerce'), $slug), 400); } } } // Validate the attribute type if (!in_array(wc_clean($type), array_keys(wc_get_attribute_types()))) { throw new WC_API_Exception('woocommerce_api_invalid_product_attribute_type', sprintf(__('Invalid product attribute type - the product attribute type must be any of these: %s', 'woocommerce'), implode(', ', array_keys(wc_get_attribute_types()))), 400); } // Validate the attribute order by if (!in_array(wc_clean($order_by), array('menu_order', 'name', 'name_num', 'id'))) { throw new WC_API_Exception('woocommerce_api_invalid_product_attribute_order_by', sprintf(__('Invalid product attribute order_by type - the product attribute order_by type must be any of these: %s', 'woocommerce'), implode(', ', array('menu_order', 'name', 'name_num', 'id'))), 400); } return true; }
/** * Get the Attribute's schema, conforming to JSON Schema. * * @return array */ public function get_item_schema() { $schema = array('$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'product_attribute', 'type' => 'object', 'properties' => array('id' => array('description' => __('Unique identifier for the resource.', 'woocommerce'), 'type' => 'integer', 'context' => array('view', 'edit'), 'readonly' => true), 'name' => array('description' => __('Attribute name.', 'woocommerce'), 'type' => 'string', 'context' => array('view', 'edit'), 'arg_options' => array('sanitize_callback' => 'sanitize_text_field')), 'slug' => array('description' => __('An alphanumeric identifier for the resource unique to its type.', 'woocommerce'), 'type' => 'string', 'context' => array('view', 'edit'), 'arg_options' => array('sanitize_callback' => 'sanitize_title')), 'type' => array('description' => __('Type of attribute.', 'woocommerce'), 'type' => 'string', 'default' => 'select', 'enum' => array_keys(wc_get_attribute_types()), 'context' => array('view', 'edit')), 'order_by' => array('description' => __('Default sort order.', 'woocommerce'), 'type' => 'string', 'default' => 'menu_order', 'enum' => array('menu_order', 'name', 'name_num', 'id'), 'context' => array('view', 'edit')), 'has_archives' => array('description' => __('Enable/Disable attribute archives.', 'woocommerce'), 'type' => 'boolean', 'default' => false, 'context' => array('view', 'edit')))); return $this->add_additional_fields_schema($schema); }